diff --git a/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md b/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md index cdbf63df..b5b1344c 100644 --- a/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md +++ b/docs-source/src/en/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md @@ -327,13 +327,17 @@ fun refreshModuleAppResources() ## onAppLifecycle - method ```kotlin:no-line-numbers -inline fun onAppLifecycle(initiate: AppLifecycle.() -> Unit) +inline fun onAppLifecycle(isOnFailureThrowToApp: Boolean, initiate: AppLifecycle.() -> Unit) ``` **Change Records** `v1.0.88` `added` +`v1.1.5` `modified` + +新增 `isOnFailureThrowToApp` 参数,可选择将异常在 (Xposed) 宿主环境打印而不是抛出给宿主 + **Function Illustrate** > 监听当前 Hook APP 生命周期装载事件。 @@ -975,13 +979,17 @@ resources().hook { ## AppLifecycle - class ```kotlin:no-line-numbers -inner class AppLifecycle internal constructor() +inner class AppLifecycle internal constructor(private val isOnFailureThrowToApp: Boolean) ``` **Change Records** `v1.0.88` `added` +`v1.1.5` `modified` + +新增 `isOnFailureThrowToApp` 参数,可选择将异常在 (Xposed) 宿主环境打印而不是抛出给宿主 + **Function Illustrate** > 当前 Hook APP 的生命周期实例处理类。 diff --git a/docs-source/src/en/api/special-features/host-lifecycle.md b/docs-source/src/en/api/special-features/host-lifecycle.md index 5c1de97f..6be8fb16 100644 --- a/docs-source/src/en/api/special-features/host-lifecycle.md +++ b/docs-source/src/en/api/special-features/host-lifecycle.md @@ -2,9 +2,9 @@ > This is an extension of the lifecycle of an automatic hooking Host App. -## Monitor Lifecycle +## Listener Lifecycle -> Implement the monitoring function by automating the lifecycle method of the Host App. +> Implement the listening function by automating the lifecycle method of the Host App. We need to listen to the startup and lifecycle methods of the Host App's `Application`, just use the following methods. @@ -13,7 +13,11 @@ We need to listen to the startup and lifecycle methods of the Host App's `Applic ```kotlin loadApp(name = "com.example.demo") { // Register lifecycle listeners - onAppLifecycle { + // Optional parameter: + // You can set isOnFailureThrowToApp = false + // So that the exception will not be thrown to the Host App to prevent the Host App from crashing + // The default is true + onAppLifecycle(isOnFailureThrowToApp = true) { // You can implement lifecycle method listeners in Application here attachBaseContext { baseContext, hasCalledSuper -> // Determine whether @@ -54,7 +58,7 @@ For more functions, please refer to [AppLifecycle](../public/com/highcapable/yuk ## Register System Broadcast -> Register system broadcast through the `Application.onCreate` method to monitor system broadcast. +> Register system broadcast through the `Application.onCreate` method to listening system broadcast. We can also register system broadcast in the Host App's `Application`. @@ -64,7 +68,7 @@ We can also register system broadcast in the Host App's `Application`. loadApp(name = "com.example.demo") { // Register lifecycle listeners onAppLifecycle { - // Broadcast monitoring when the registered user is unlocked + // Broadcast listening when the registered user is unlocked registerReceiver(Intent.ACTION_USER_PRESENT) { context, intent -> // ... } diff --git a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md index a96529a0..ec6e4176 100644 --- a/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md +++ b/docs-source/src/zh-cn/api/public/com/highcapable/yukihookapi/hook/param/PackageParam.md @@ -319,13 +319,17 @@ fun refreshModuleAppResources() ## onAppLifecycle - method ```kotlin:no-line-numbers -inline fun onAppLifecycle(initiate: AppLifecycle.() -> Unit) +inline fun onAppLifecycle(isOnFailureThrowToApp: Boolean, initiate: AppLifecycle.() -> Unit) ``` **变更记录** `v1.0.88` `新增` +`v1.1.5` `修改` + +新增 `isOnFailureThrowToApp` 参数,可选择将异常在 (Xposed) 宿主环境打印而不是抛出给宿主 + **功能描述** > 监听当前 Hook APP 生命周期装载事件。 @@ -967,13 +971,17 @@ resources().hook { ## AppLifecycle - class ```kotlin:no-line-numbers -inner class AppLifecycle internal constructor() +inner class AppLifecycle internal constructor(private val isOnFailureThrowToApp: Boolean) ``` **变更记录** `v1.0.88` `新增` +`v1.1.5` `修改` + +新增 `isOnFailureThrowToApp` 参数,可选择将异常在 (Xposed) 宿主环境打印而不是抛出给宿主 + **功能描述** > 当前 Hook APP 的生命周期实例处理类。 diff --git a/docs-source/src/zh-cn/api/special-features/host-lifecycle.md b/docs-source/src/zh-cn/api/special-features/host-lifecycle.md index 9980020b..eb7739aa 100644 --- a/docs-source/src/zh-cn/api/special-features/host-lifecycle.md +++ b/docs-source/src/zh-cn/api/special-features/host-lifecycle.md @@ -13,7 +13,8 @@ ```kotlin loadApp(name = "com.example.demo") { // 注册生命周期监听 - onAppLifecycle { + // 可选参数:你可以设置 isOnFailureThrowToApp = false 使得其中的异常不会抛出给宿主防止宿主崩溃,默认为 true + onAppLifecycle(isOnFailureThrowToApp = true) { // 你可以在这里实现 Application 中的生命周期方法监听 attachBaseContext { baseContext, hasCalledSuper -> // 通过判断 hasCalledSuper 来确定是否已执行 super.attachBaseContext(base) 方法 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt index 3422ffc1..7589d90b 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt @@ -210,9 +210,11 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: * - ❗在 [loadZygote] 中不会被装载 - 仅会在 [loadSystem]、[loadApp] 中装载 * * - ❗作为 Hook API 装载时请使用原生的 [Application] 实现生命周期监听 + * @param isOnFailureThrowToApp 是否在发生异常时将异常抛出给宿主 - 默认是 * @param initiate 方法体 */ - inline fun onAppLifecycle(initiate: AppLifecycle.() -> Unit) = AppLifecycle().apply(initiate).build() + inline fun onAppLifecycle(isOnFailureThrowToApp: Boolean = true, initiate: AppLifecycle.() -> Unit) = + AppLifecycle(isOnFailureThrowToApp).apply(initiate).build() /** * 装载并 Hook 指定包名的 APP @@ -597,8 +599,9 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: * 当前 Hook APP 的生命周期实例处理类 * * - ❗请使用 [onAppLifecycle] 方法来获取 [AppLifecycle] + * @param isOnFailureThrowToApp 是否在发生异常时将异常抛出给宿主 */ - inner class AppLifecycle @PublishedApi internal constructor() { + inner class AppLifecycle @PublishedApi internal constructor(private val isOnFailureThrowToApp: Boolean) { /** * 监听当前 Hook APP 装载 [Application.attachBaseContext] @@ -660,6 +663,7 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: /** 设置创建生命周期监听回调 */ @PublishedApi internal fun build() { + AppParasitics.AppLifecycleCallback.isOnFailureThrowToApp = isOnFailureThrowToApp AppParasitics.AppLifecycleCallback.isCallbackSetUp = true } } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt index c7e76a40..62714acf 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt @@ -41,6 +41,7 @@ import android.content.res.Resources import android.os.Handler import com.highcapable.yukihookapi.YukiHookAPI import com.highcapable.yukihookapi.hook.factory.* +import com.highcapable.yukihookapi.hook.log.loggerE import com.highcapable.yukihookapi.hook.log.yLoggerE import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.param.type.HookEntryType @@ -48,6 +49,7 @@ import com.highcapable.yukihookapi.hook.type.android.* import com.highcapable.yukihookapi.hook.type.java.* import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiModuleResources +import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookCallback import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiMemberHook import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiMemberReplacement @@ -167,6 +169,14 @@ internal object AppParasitics { * @param packageName 包名 */ internal fun registerToAppLifecycle(packageName: String) { + /** + * 向当前 Hook APP (宿主) 抛出异常或打印错误日志 + * @param throwable 当前异常 + */ + fun YukiHookCallback.Param.throwToAppOrLogger(throwable: Throwable) { + if (AppLifecycleCallback.isOnFailureThrowToApp) this.throwable = throwable + else loggerE(msg = "An exception occurred during AppLifecycle event", e = throwable) + } /** Hook [Application] 装载方法 */ runCatching { if (AppLifecycleCallback.isCallbackSetUp) { @@ -174,27 +184,27 @@ internal object AppParasitics { override fun beforeHookedMember(param: Param) { runCatching { (param.args?.get(0) as? Context?)?.also { AppLifecycleCallback.attachBaseContextCallback?.invoke(it, false) } - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } override fun afterHookedMember(param: Param) { runCatching { (param.args?.get(0) as? Context?)?.also { AppLifecycleCallback.attachBaseContextCallback?.invoke(it, true) } - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onTerminate" }, object : YukiMemberHook() { override fun afterHookedMember(param: Param) { runCatching { (param.instance as? Application?)?.also { AppLifecycleCallback.onTerminateCallback?.invoke(it) } - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onLowMemory" }, object : YukiMemberHook() { override fun afterHookedMember(param: Param) { runCatching { (param.instance as? Application?)?.also { AppLifecycleCallback.onLowMemoryCallback?.invoke(it) } - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onTrimMemory"; param(IntType) }, object : YukiMemberHook() { @@ -203,7 +213,7 @@ internal object AppParasitics { val self = param.instance as? Application? ?: return val type = param.args?.get(0) as? Int? ?: return AppLifecycleCallback.onTrimMemoryCallback?.invoke(self, type) - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onConfigurationChanged" }, object : YukiMemberHook() { @@ -212,7 +222,7 @@ internal object AppParasitics { val self = param.instance as? Application? ?: return val config = param.args?.get(0) as? Configuration? ?: return AppLifecycleCallback.onConfigurationChangedCallback?.invoke(self, config) - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } }) } @@ -241,7 +251,7 @@ internal object AppParasitics { isDataChannelRegistered = true } } - }.onFailure { param.throwable = it } + }.onFailure { param.throwToAppOrLogger(it) } } }) } @@ -352,6 +362,9 @@ internal object AppParasitics { /** 是否已设置回调 */ internal var isCallbackSetUp = false + /** 是否在发生异常时将异常抛出给宿主 */ + internal var isOnFailureThrowToApp = true + /** [Application.attachBaseContext] 回调 */ internal var attachBaseContextCallback: ((Context, Boolean) -> Unit)? = null