如何启动未经注册的activity和service

本文探讨了如何在安卓系统中启动未经注册的Activity和Service,涉及ActivityThread作为应用入口、UI线程与Looper的关系、AMS交互以及hook、反射等技术。通过理解activity启动流程和坑位埋点概念,借助ContextImp和ActivityManager,实现了未注册组件的启动。项目结构包括App、Plugin以及使用坑位组件StubActivity和StubService。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

涉及到的关键类:ActivityThread,ContextImp,ActivityManager

涉及到的技术:activity启动流程,hook(也就是动态代理),java反射,AMS的交互过程

ActivityThread:

ActivityThread位于android.app包下,他是安卓应用的真正入口,以下代码拷贝自android SDK 26中,去掉了注释部分

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        EventLogger.setReporter(new EventLoggingReporter());
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        Process.setArgV0("<pre-initialized>");
        //准备ui线程的Looper,这也是为什么我们平时可以直接在ui线程中使用handler的原因,而子线程中必须手工进行初始化。
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            //就是mH,它是一个handler
            sMainThreadHandler = thread.getHandler();
        }
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        //开始loop,这里面就开始无限循环了,如果这里结束了那么就表示整个应用程序结束了
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
}
  •  

通过这段代码我们可以得到几个知识点,简单进行下总结:

  • 安卓应用程序的入口是什么?

    ActivityThread?Application?Activity? 想必大家也都知道答案了吧,真正的入口只有一个,就是ActivityThread

  • 为什么在子线程中需要手工进行Looper的初始化?

    因为在ui线程中,系统已经默认帮我们初始化了,而在子线程中必须手工进行初始化,可以参考HandlerThread

  • 安卓不能在ui线程中执行耗时操作,但是在程序的入口处却开始了无限循环,这种现象如何解释?

    准确的说不能再ui线程中进行耗时操作,指的是四大组件中的生命周期内不能进行耗时操作。而Looper的无限循环是Handler异步通讯的基础,不能结束,如果结束了,就代表应用程序结束了。ANR的异常检查是在AMS中进行校验的,可以参考 http://blog.youkuaiyun.com/vrix/article/details/54134124

ContextImp:

安卓四大组件运行时的上下文环境,以下代码拷贝自android SDK 26中,去掉了注释部分
代码路径为ActivityThread.handleLaunchActivity() -> performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
        //开始创建ContextImp
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值