前言
主线程的Handler 主要依赖于 ActivityThread,Android是消息驱动,比如view的刷新,activity的创建等,如果能打印系统层Handler消息日志,就需要对于系统层的Handler 进行Hook
原理
ActivityThread中 mH对象主要负责整个主线程的事件传递,拿到mH传递的消息并打印出来,就可以,Handler的消息处理机制,会先处理Message的Callback 再处理handlerMessage
核心代码
ActivityThread.java
final H mH = new H();
class H extends Handler {
public static final int BIND_APPLICATION = 110;
@UnsupportedAppUsage
public static final int EXIT_APPLICATION = 111;
@UnsupportedAppUsage
public static final int RECEIVER = 113;
...
public static final int EXECUTE_TRANSACTION = 159;
}
Handler.java
public void dispatchMessage(@NonNull Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
如果能给系统的Handler 设置上 callback ,那每次系统消息传递 就可以先回调我们的callback
只要我们返回false ,系统正常运行,因为mH是静态的,通过代码反射invoke的就是系统的,
再反射获取 Handler的mCallback对象,设置我们自己的Callback实现类即可
源码
private void hookSystemHandler() throws IllegalAccessException, NoSuchFieldException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
//获取静态ActivityThread对象
Object currentActivityThread = activityThreadClass.getDeclaredMethod("currentActivityThread").invoke(null);
Field mHField = activityThreadClass.getDeclaredField("mH");
mHField.setAccessible(true);
//获取mH对象 系统的
Object mH = mHField.get(currentActivityThread);
Field mCallbackField =Handler.class.getDeclaredField("mCallback");
mCallbackField.setAccessible(true);
//替换为我们的Callback
mCallbackField.set(mH,new MyHookHandler());
}
class MyHookHandler implements Handler.Callback {
public MyHookHandler() {
}
@Override
public boolean handleMessage(@NonNull Message msg) {
//我们的Handler 已经完成了替换
//这里对所有系统消息进行拦截
Log.d("tag-message",msg.toString());
// 要保证系统运行正常 还得让原本handler 继续处理
// originalHandler.handleMessage(msg);
return false; //不拦截
}
}
最终效果
D { when=-1ms what=159 obj=android.app.servertransaction.ClientTransaction@196c92db target=android.app.ActivityThread$H }
D { when=-6ms what=159 obj=android.app.servertransaction.ClientTransaction@9bc76abb target=android.app.ActivityThread$H }
D { when=-20ms what=159 obj=android.app.servertransaction.ClientTransaction@18771a77 target=android.app.ActivityThread$H }