Added Activity Proxy function

This commit is contained in:
2022-08-15 05:00:11 +08:00
parent 0f5ec1c912
commit 0ea5f520d1
13 changed files with 1024 additions and 3 deletions

View File

@@ -24,6 +24,10 @@
[filename](public/ModuleApplication.md ':include')
[filename](public/ModuleAppActivity.md ':include')
[filename](public/ModuleAppCompatActivity.md ':include')
[filename](public/YukiModuleResources.md ':include')
[filename](public/YukiResources.md ':include')

View File

@@ -0,0 +1,17 @@
## ModuleAppActivity [class]
```kotlin
open class ModuleAppActivity : Activity()
```
**变更记录**
`v1.0.93` `新增`
**功能描述**
> 代理 `Activity`。
继承于此类的 `Activity` 可以同时在宿主与模块中启动。
在 (Xposed) 宿主环境需要在宿主启动时调用 `Context.registerModuleAppActivities` 进行注册。

View File

@@ -0,0 +1,33 @@
## ModuleAppCompatActivity [class]
```kotlin
open class ModuleAppCompatActivity : AppCompatActivity()
```
**变更记录**
`v1.0.93` `新增`
**功能描述**
> 代理 `AppCompatActivity`。
继承于此类的 `Activity` 可以同时在宿主与模块中启动。
在 (Xposed) 宿主环境需要在宿主启动时调用 `Context.registerModuleAppActivities` 进行注册。
在 (Xposed) 宿主环境需要重写 `moduleTheme` 设置 AppCompat 主题,否则会无法启动。
### moduleTheme [field]
```kotlin
open val moduleTheme: Int
```
**变更记录**
`v1.0.93` `新增`
**功能描述**
> 设置当前代理的 `Activity` 主题。

View File

@@ -191,6 +191,150 @@ onAppLifecycle {
}
```
### registerModuleAppActivities [method]
```kotlin
fun Context.registerModuleAppActivities(proxy: Any?)
```
**变更记录**
`v1.0.93` `新增`
**功能描述**
> 向 Hook APP (宿主) 注册当前 Xposed 模块的 `Activity`。
注册成功后,你就可以直接使用 `Context.startActivity` 来启动未在宿主中注册的 `Activity`
你要将需要在宿主启动的 `Activity` 继承于 `ModuleAppActivity``ModuleAppCompatActivity`
为防止资源 ID 互相冲突,你需要在当前 Xposed 模块项目的 `build.gradle` 中修改资源 ID。
- Kotlin Gradle DSL
```kotlin
androidResources.additionalParameters("--allow-reserved-package-id", "--package-id", "0x64")
```
- Groovy
```groovy
aaptOptions.additionalParameters '--allow-reserved-package-id', '--package-id', '0x64'
```
!> 提供的示例资源 ID 值仅供参考,为了防止当前宿主存在多个 Xposed 模块,建议自定义你自己的资源 ID。
!> 只能在 (Xposed) 宿主环境使用此功能,其它环境下使用将不生效且会打印警告信息。
**功能示例**
在 Hook 宿主之后,我们可以直接在 Hooker 中得到的 `Context` 注册当前模块的 `Activity` 代理。
> 示例如下
```kotlin
injectMember {
method {
name = "onCreate"
param(BundleClass)
}
afterHook {
instance<Activity>().registerModuleAppActivities()
}
}
```
你还可以直接在 `AppLifecycle` 中注册当前模块的 `Activity` 代理。
> 示例如下
```kotlin
onAppLifecycle {
onCreate {
registerModuleAppActivities()
}
}
```
如果没有填写 `proxy` 参数API 将会根据当前 `Context` 自动获取当前宿主的启动入口 `Activity` 进行代理。
通常情况下,它是有效的,但是以上情况在一些 APP 中会失效,例如一些 `Activity` 会在注册清单上加入启动参数,那么我们就需要使用另一种解决方案。
若未注册的 `Activity` 不能被正确启动,我们可以手动拿到宿主的 `AndroidManifest.xml` 进行分析,来得到一个注册过的 `Activity` 标签,获取其中的 `name`
你需要选择一个当前宿主可能用不到的、不需要的 `Activity` 作为一个“傀儡”将其进行代理,通常是有效的。
比如我们已经找到了能够被代理的合适 `Activity`
> 示例如下
```xml
<activity
android:name="com.demo.test.activity.TestActivity"
...>
```
根据其中的 `name`,我们只需要在方法中加入这个参数进行注册即可。
> 示例如下
```kotlin
registerModuleAppActivities(proxy = "com.demo.test.activity.TestActivity")
```
另一种情况,如果你对宿主的类编写了一个 `stub`,那么你可以直接通过 `Class` 对象来进行注册。
> 示例如下
```kotlin
registerModuleAppActivities(TestActivity::class.java)
```
注册完成后,请将你需要使用宿主启动的模块中的 `Activity` 继承于 `ModuleAppActivity``ModuleAppCompatActivity`
这些 `Activity` 现在无需注册即可无缝存活于宿主中。
> 示例如下
```kotlin
class HostTestActivity : ModuleAppActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 模块资源已被自动注入,可以直接使用 xml 装载布局
setContentView(R.layout.activity_main)
}
}
```
若你需要继承于 `ModuleAppCompatActivity`,你需要手动设置 AppCompat 主题。
> 示例如下
```kotlin
class HostTestActivity : ModuleAppCompatActivity() {
// 这里的主题名称仅供参考,请填写你模块中已有的主题名称
override val moduleTheme get() = R.style.Theme_AppCompat
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 模块资源已被自动注入,可以直接使用 xml 装载布局
setContentView(R.layout.activity_main)
}
}
```
以上步骤全部完成后,你就可以在 (Xposed) 宿主环境任意存在 `Context` 的地方愉快地调用 `startActivity` 了。
> 示例如下
```kotlin
val context: Context = ... // 假设这就是你的 Context
context.startActivity(context, HostTestActivity::class.java)
```
### ~~isSupportResourcesHook [field]~~ <!-- {docsify-ignore} -->
**变更记录**