Gradle插件化
implementation gradleApi()
实现Plugin<Project>接口
引用插件 apply plugin 'xxx'
project.getExtensions().create(...)
mapping.txt 混淆前后对照表
-applymapping mapping.txt 按照混淆表进行混淆
transformClassesAndResourcesWithProguardXX 混淆任务
class的md5值校验对比
360插件化
- 创建DexClassLoader 反射获取 dexElements值
- 获取宿主的PathClassLoader 反射获取宿主的dexElements值
- 合并插件和宿主的dexElements生成新的Element[]
- 反射将新的Element[]给宿主的dexElements
Hook Activity
Activity启动流程
Context startActivity --> ContextImpl startActivity -->
在ContextImpl 中通过 Instrumentation startActivity (跨进程过程) -->
AMS 校验Activity的合法性 通过ApplicationThread回调到自己的进程中 -->
ApplicationThread本质是一个binder 回调逻辑是在binder线程池中完成 -->
通过 H (Handler) 切换到UI线程 发送LAUNCH_ACTIVITY(8.0之前) 对应 handleLauncahActivity 完成Activity的创建和启动
Hook点的原则
- 静态变量或者单例对象
- public对象和方法
ActivityManager.getService() 获取 IActivityManager
使用动态代理替换IActivityManager 的startActivity()
Class<?> iActivityManagerClass=Class.forName("android.app.IActivityManager");
Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{iActivityManagerClass},new InvocationHandler(){
public object invoke(...){
//IActivityManager方法执行时,先执行此处进行替换Intent
}
});
通过ActivityManager反射获取到Singleton对象
反射获取Singleton的mInstance 即为IActivityManager对象
(mInstance不是静态 Singleton是静态直接反射获取)
在AMS检测前替换正常Activity 检测完后替换需要跳转的Activity
ActivityThread scheduleLaunchActivity -->
sendMessage --> handleMessage --> ActivityClientRecord r对象包含intent -->
(ActivityClientRecord)msg.obj (说明 拿到msg即可获取到intent 在onCreate之前获取)
反射Handler 通过dispathMessage(Handler)创建Callback替换原本空的Callback
Handler对象 --> ActivityThread --> final H mh = new H(); (非静态) -->
private static volatile ActivityThread sCurrentActivityThread
API > 28 加入生命周期管理 msg.obj 对应 ClientTransaction对象
ClientTransaction --> mActivityCallbacks -->
List<ClientTransactionItem> --> LaunchActivityItem
Resource类和AssetManager类 资源加载
Resource类也是通过AssetManager类访问编译过的应用资源
但访问前会根据资源ID查找对应的资源文件名
AssetManager类既可以通过文件名查找对应编译过的 也可以查找未被编译过的
ResourceManager --> AssetManager 通过 addAssetPath() --> 设置资源插件的路径 并创建Resources
raw和assets文件夹的区别 raw会生成ID