type
status
date
slug
summary
tags
category
icon
password
Android中的插件化和热修复已经应用了很多年了,这里面涉及的主要就是Hook,即反射 + 代理的技巧去实现一些常规代码无法实现的功能.
之前有说过Hook点击事件的方式,这里讲一下拦截Activity的Hook方法,这也是插件化的基础.
前提
在进行Hook之前,我们必须熟悉源码,找到可以反射的的点,然后进行替换,这里要拦截Activity的启动,那么肯定得看下Activity的启动流程.具体的就不说了,其实最后会执行到
Instrumentation
中的execStartActivity
方法.有下面这些点我们可以知道:
- 应用层可以访问到
Instrumentation
类,因此可以实现一个它的子类,重写一些方法进行替换
Activity
和ActivityThread
中持有了Instrumentation
对象,字段名为mInstrumentation
,因此可以利用反射获取到这个字段
- 启动Activity肯定会调用到
Instrumentation#execStartActivity
方法,因此这个就是替换点了
看到上面的3个点,思路基本上就清晰了.从
Activity
或者ActivityThread
中反射拿到mInstrumentation
字段,然后替换成自己的Instrumentation
实现,重写execStartActivity
方法,然后在应用代码中进行替换.源码
其实有两种思路,一个是从
Activity
入手,一个是从ActivityThread
入手.从Activity
入手
fun hookInstrumentationWithActivity(sourceActivity:Activity, callback: ActivityStartingCallback){ val instrumentationField = Activity::class.java.getDeclaredField("mInstrumentation") if (!instrumentationField.isAccessible){ instrumentationField.isAccessible = true } val originInstrumentation:Instrumentation = instrumentationField.get(sourceActivity) as Instrumentation instrumentationField.set(sourceActivity,ProxyInstrumentation(originInstrumentation,callback)) }
这种方式,需要传入Activity对象,并不是很实用.
从ActivityThread
入手
fun hookInstrumentation(callback: ActivityStartingCallback) { //获取ActivityThread类 val activityThreadClass = Class.forName("android.app.ActivityThread") val currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread") currentActivityThreadMethod.isAccessible = true val currentActivityThread = currentActivityThreadMethod.invoke(null) val mInstrumentationField = activityThreadClass.getDeclaredField("mInstrumentation") mInstrumentationField.isAccessible = true val mInstrumentation = mInstrumentationField[currentActivityThread] as Instrumentation val proxyInstrumentation: Instrumentation = ProxyInstrumentation(mInstrumentation,callback) //替换 mInstrumentationField[currentActivityThread] = proxyInstrumentation }
这种方式不需要传入Activity,直接在Application初始化过程中注入即可.
源码地址
- 作者:姜康
- 链接:https://jiangkang.tech/article/8e96ef3a-229a-459b-b488-8fcfa3628a39
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章