一、整体回顾
因为 Activity 等四大组件是有生命周期的,所以我们不能仅仅只是将其通过 ClassLoader 加载进来,还需要通过 Intent 将其启动。又由于插件Apk 不在项目中,所以我们不能实现类似:
startActivity(new Intent(this, PluginActivity.class))
因为压根就找不到 PluginActivity ,所以我们只能通过 Compunent 的方式:
1 | Intent intent = new Intent(); |
通过包名和路径的方式去找到这个 Activity 。
通过 动态代理和 反射 去实现 Hook 技术,以便欺骗 AMS 对 Activity 的是否注册。查找 Hook 点的原则:
尽量是静态变量或者单例对象
尽量Hook public 的对象和方法
二、启动插件中的 Activity
其实插件化的Hook 流程如下图所示:
所以我们的思路是:
在进入 AMS 之前,找到 Hook 点将目标 Activity 替换成占位 Activity (在宿主的 AndroidManifest中注册了的)
在从 AMS 中返回 App 的时候,将占位 Activity 换回 目标 Activity
所以,其实整个过程都是在找 startActivity 时候传入的 Intent ,只需要正确找到替换 Intent 的地方就行。
三、适配和总结
判断某个点是否可以Hook,就需要反推,一直往前面找调用方,一直找到有对象的,或者是静态的地方,就可以从那里开始了。