启动一个没有注册的Activity

废话不多说,直接上代码 ,如有不明白的可以私信留言,一起进步

在Application 中调用即可(AndroidManifest 中已经有注册过的activity)
class App extends Application{
@Override
public void onCreate(){
HookStartActivityIml.getInstance(getApplicationContext()).init();
}
}

HookStartActivityIml.java 的具体实现

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class HookStartActivityIml {

private String EXTRA_TARGET_INTENT = "wdd_test";
private static HookStartActivityIml hookStartActivityIml= null;
private Context context;
private String activityClass;//占坑
public static HookStartActivityIml getInstance(Context context){
    if (hookStartActivityIml==null){
        synchronized (HookStartActivityIml.class){
            if (hookStartActivityIml== null){
                hookStartActivityIml = new HookStartActivityIml(context);
            }
        }
    }
    return hookStartActivityIml;
}
private HookStartActivityIml(Context context){
    this.context = context;
    try {
        PackageManager packageManager = context.getPackageManager();
        String packageName = context.getPackageName();
        PackageInfo packageInfo = packageManager.getPackageInfo(packageName,PackageManager.GET_ACTIVITIES);
        //activity信息
        ActivityInfo[] activities = packageInfo.activities;
       if (activities.length>0)
           activityClass = activities[0].name;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }

}

public void init(){
    hookStartActivity();
    hookActivityThread();
}


private void hookStartActivity(){
    try {
        Field enterField = null;
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            Class activityManagerClass = Class.forName("android.app.ActivityManager");
            //Field IActivityManagerSingleton
            enterField = activityManagerClass.getDeclaredField("IActivityManagerSingleton");
        } else {
            Class activityManagerNative = Class.forName("android.app.ActivityManagerNative");
            enterField = activityManagerNative.getDeclaredField("gDefault");
        }

        enterField.setAccessible(true);
        //Singleton<IActivityManager>的实例,因为IActivityManagerSingleton是静态的
        Object singletonObject = enterField.get(null);


        Class singletonClass = Class.forName("android.util.Singleton");
        Field mInstanceField = singletonClass.getDeclaredField("mInstance");
        mInstanceField.setAccessible(true);
        // 获取singletonObject中变量mInstance的值即IActivityManager类型的实例
        final Object mIActivityManagerObject = mInstanceField.get(singletonObject);

        //IActivityManager 是接口,通过动态代理来处理
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Class iActivityManagerInterface = Class.forName("android.app.IActivityManager");

        //生产IActivityManager的代理对象
        Object mIActivityManagerProxy = Proxy.newProxyInstance(
                classLoader, new Class[]{iActivityManagerInterface}, new InvocationHandler() {

                    @Override public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {

                        if ("startActivity".equals(method.getName())) {
                            Intent rawIntent = null;
                            int index = 0;
                            for (int i = 0; i < args.length; i++) {
                                if (args[i] instanceof Intent) {
                                    rawIntent = (Intent) args[i];
                                    index = i;
                                    break;
                                }
                            }


                            // 将需要被启动的Activity替换成StubActivity
                            Intent newIntent = new Intent();
                            newIntent.setClassName(context, activityClass);
                            //把这个newIntent放回到args,达到了一个欺骗AMS的目的
                            newIntent.putExtra(EXTRA_TARGET_INTENT, rawIntent);
                            //将原有的Bundle添加到新的intent上
                            if (rawIntent.getExtras()!=null)
                           		 newIntent.putExtras(rawIntent.getExtras());
                            args[index] = newIntent;

                        }

                        return method.invoke(mIActivityManagerObject, args);
                    }
                });

        //把我们的代理对象融入到framework
        //IActivityManager 在源码中是AIDL
        mInstanceField.set(singletonObject, mIActivityManagerProxy);

    } catch (Exception e) {
        e.printStackTrace();

    }
}

private void hookActivityThread(){
    try {

        Class launchActivityClass = Class.forName("android.app.ActivityThread");
        Field mCurrentActivityThreadFiled = launchActivityClass.getDeclaredField("sCurrentActivityThread");

        // 获取ActivityThread的实例
        mCurrentActivityThreadFiled.setAccessible(true);
        Object currentActivityThreadObject = mCurrentActivityThreadFiled.get(null);

        //获取H
        Field mHFiled = launchActivityClass.getDeclaredField("mH");
        //H的实例
        mHFiled.setAccessible(true);
        Handler hObject = (Handler) mHFiled.get(currentActivityThreadObject);

        //获取callback
        Field mCallbackField = Handler.class.getDeclaredField("mCallback");
        mCallbackField.setAccessible(true);

        // TODO 为什么不需要动态代理了?
        mCallbackField.set(hObject, new Handler.Callback() {
            @Override public boolean handleMessage(Message msg) {
                Object obj = msg.obj;
                switch (msg.what) {
                    case 100:
                        try {
                            Field intnetField = obj.getClass().getDeclaredField("intent");
                            intnetField.setAccessible(true);
                            Intent proxyIntent = (Intent) intnetField.get(obj);
                            Intent realinIntent = proxyIntent.getParcelableExtra(EXTRA_TARGET_INTENT);
                            if(realinIntent!=null){
                                proxyIntent.setComponent(realinIntent.getComponent());//替换
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                    case 149:
                    case 159:
                        //恢复真身
                        //Object obj = msg.obj;
                        try {
                            if (Build.VERSION.SDK_INT < 28) {
                                try {
                                    Field intnetField = obj.getClass().getDeclaredField("intent");
                                    intnetField.setAccessible(true);
                                    Intent proxyIntent = (Intent) intnetField.get(obj);
                                    Intent realinIntent = proxyIntent.getParcelableExtra(EXTRA_TARGET_INTENT);
                                    if(realinIntent!=null){
                                        proxyIntent.setComponent(realinIntent.getComponent());//替换
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            } else {
                                Field mActivityCallbacksField = obj.getClass().getDeclaredField("mActivityCallbacks");
                                mActivityCallbacksField.setAccessible(true);
                                List mActivityCallbacks = (List) mActivityCallbacksField.get(obj);

                                if (mActivityCallbacks.size() > 0) {
                                    String className = "android.app.servertransaction.LaunchActivityItem";
                                    if (mActivityCallbacks.get(0).getClass().getCanonicalName().equals(className)) {
                                        Object object = mActivityCallbacks.get(0);
                                        Field intentField = object.getClass().getDeclaredField("mIntent");
                                        intentField.setAccessible(true);
                                        Intent intent = (Intent) intentField.get(object);
                                        Intent targetIntent = intent.getParcelableExtra(EXTRA_TARGET_INTENT);
                                        if (targetIntent != null) {
                                            intent.setComponent(targetIntent.getComponent());
                                        }

                                    }
                                }
                            }
                        } catch(Exception e){
                            e.printStackTrace();
                        }


                        break;
                }
                return false;
            }
        });


    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值