package com.huanju.chajianhuatest.ams;
import android.os.Handler;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author 刘镓旗
* @date 17/2/21
*/
public class AMSHookHelper {
public static final String EXTRA_TARGET_INTENT = "extra_target_intent";
public static int LAUNCH_ACTIVITY;
/**
* Hook AMS
* <p/>
* 主要完成的操作是 "把真正要启动的Activity临时替换为在AndroidManifest.xml中声明的替身Activity"
* <p/>
* 进而骗过AMS
*
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchFieldException
*/
public static void hookActivityManagerNative() throws ClassNotFoundException,
NoSuchMethodException, InvocationTargetException,
IllegalAccessException, NoSuchFieldException {
//获取ActivityManagerNative的类
Class<?> activityManagerNativeClass = Class.forName("android.app.ActivityManagerNative");
//拿到gDefault字段
Field gDefaultField = activityManagerNativeClass.getDeclaredField("gDefault");
gDefaultField.setAccessible(true);
//从gDefault字段中取出这个对象的值
Object gDefault = gDefaultField.get(null);
// gDefault是一个 android.util.Singleton对象; 我们取出这个单例里面的字段
Class<?> singleton = Class.forName("android.util.Singleton");
//这个gDefault是一个Singleton类型的,我们需要从Singleton中再取出这个单例的AMS代理
Field mInstanceField = singleton.getDeclaredField("mInstance");
mInstanceField.setAccessible(true);
//ams的代理对象
Object rawIActivityManager = mInstanceField.get(gDefault);
// 创建一个这个对象的代理对象, 然后替换这个字段, 让我们的代理对象帮忙干活,这里我们使用动态代理
Class<?> iActivityManagerInterface = Class.forName("android.app.IActivityManager");
Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { iActivityManagerInterface }, new IActivityManagerHandler(rawIActivityManager));
mInstanceField.set(gDefault, proxy);
}
/**
* 由于之前我们用替身欺骗了AMS; 现在我们要换回我们真正需要启动的Activity
* <p/>
* 不然就真的启动替身了, 狸猫换太子...
* <p/>
* 到最终要启动Activity的时候,会交给ActivityThread 的一个内部类叫做 H 来完成
* H 会完成这个消息转发; 最终调用它的callback
*/
public static void hookActivityThreadHandler() throws Exception {
// 先获取到当前的ActivityThread对象
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
//他有一个方法返回了自己
Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
currentActivityThreadMethod.setAccessible(true);
//执行方法得到ActivityThread对象
Object currentActivityThread = currentActivityThreadMethod.invoke(null);
// 由于ActivityThread一个进程只有一个,我们获取这个对象的mH
Field mHField = activityThreadClass.getDeclaredField("mH");
mHField.setAccessible(true);
//得到H这个Handler
Handler mH = (Handler) mHField.get(currentActivityThread);
Field mCallBackField = Handler.class.getDeclaredField("mCallback");
mCallBackField.setAccessible(true);
//设置我们自己的CallBackField
mCallBackField.set(mH, new ActivityThreadHandlerCallback(mH));
}
}