type
status
date
slug
summary
tags
category
icon
password
Android中的插件化和热修复已经应用了很多年了,这里面涉及的主要就是Hook,即反射 + 代理的技巧去实现一些常规代码无法实现的功能.
之前有说过Hook点击事件的方式,这里讲一下拦截Activity的Hook方法,这也是插件化的基础.

前提

在进行Hook之前,我们必须熟悉源码,找到可以反射的的点,然后进行替换,这里要拦截Activity的启动,那么肯定得看下Activity的启动流程.具体的就不说了,其实最后会执行到Instrumentation中的execStartActivity方法.
有下面这些点我们可以知道:
  • 应用层可以访问到Instrumentation类,因此可以实现一个它的子类,重写一些方法进行替换
  • ActivityActivityThread中持有了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初始化过程中注入即可.

源码地址

Java队列Hook点击事件
姜康
姜康
一个软件工程师
公告
type
status
date
slug
summary
tags
category
icon
password
🎉博客网站重新制作了🎉
👏欢迎更新体验👏