Android插件化之启动Activity

本文探讨Android插件化技术中如何启动未在AndroidManifest.xml预注册的Activity。分析Activity的启动流程,从app进程发起请求到系统服务AMS响应,详细阐述在不修改AMS的前提下,插件化框架如何实现动态启动Activity的机制。

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

在上一篇文章Android插件化之ClassLoader我们已经可以成功加载apk,但是还没有办法启动插件中的Activity。我们知道,如果要启动一个Activity,那么这个Activity必须在AndroidManifest.xml中注册。因此,如果我们要启动插件中的Activity,那么这个Activity事先必须在宿主的AndroidManifest.xml中预注册。这样一来就会有两个问题:

  1. 插件中的Activity在宿主的AndroidManifest.xml中注册,开发不太友好。
  2. 只能启动插件中事先定义好的Activity,没有办法动态增加Activity

因此,现有的插件化框架都会有一套越过AndroidManifest.xml注册而启动Activity的机制。本文的目的就是分析这套机制。

Activity的启动流程

不考虑多进程的情况,Activity的启动是Binder双向通信的一个过程,它由我们的app进程和AMS所在的system_server进程共同完成。system_server是一个系统级的进程,其内部的AMS负责管理所有app的Activity状态。因此,Android是不允许我们对AMS进行修改的。那么,插件化技术只能在我们app进程里做文章了。

下图我根据6.0的源码画出了Activity的启动流程图,我省略了我们不需要关心的AMS部分。
在这里插入图片描述
正如上图所示,我将Activity的启动流程分为了两部分。上部分描述了app从发起启动activity请求到AMS接受到该请求的过程。下部分描述了AMS处理完成后响应app进程启动Activity的过程

请求阶段
在这里插入图片描述
上图无论是Activity的statActivity()还是startActivityForResult()最终都调用了Instrumentation.execStartActivity()。我们继续定位到Instrumentation.execStartActivity()。
在这里插入图片描述
execStartActivity()非常简单。它将传进来的参数进一步包装后传给ActivityManagerNative.getDefault()的startActivity()。ActivityManagerNative.getDefault()返回的其实是一个ActivityManagerProxy对象。ActivityManagerProxy是ActivityManagerService在app进程中的Binder代理对象。调用ActivityManagerProxy.startService()最后会调用ActivityManagerService.startService()。这样请求就到了ActivityManagerService。ActivityManagerNative.getDefault()如下:

在这里插入图片描述
到此,请求启动Activity的过程就分析完了。

响应阶段

前面我们提到过,在不考虑多进程的情况下,Activity的启动过程是一个Binder双向通信的过程。AMS要主动与app进程通信要依靠请求启动Activity阶段传过来的IBinder对象,这个IBinder对象就是上面介绍过的Instrumentation.execStartActivity()中的 whoThread对象,它实际上是一个ApplicationThreadProxy对象,用来和ApplicationThread通信。AMS通知app进程启动Activity是通过调用ApplicationThreadProxy.scheduleLaunchActivity()完成的。根据Binder通信,ApplicationThread.scheduleLaunchActivity()会被调用。我们就从ApplicationThread.scheduleLaunchActivity()开始分析。
在这里插入图片描述
scheduleLaunchActivity()将从AMS中传过来的参数封装成ActivityClientRecord对象,然后将消息发送给mH,mH是一个Handler对象。
在这里插入图片描述
H是ActivityThread的内部类,继承自Handler,它在收到LAUNCH_ACTIVITY的消息后,会调用ActivityThread.handlerLaunchActivity()。
在这里插入图片描述handleLaunchActivity()主要调用了两个方法:performLaunchActivity()和handleResumeActivity()。performLaunchActivity()会完成Activity的创建,以及调用Activity的onCreate()、onStart()等方法。handleResumeActivity()会完成Activity.onResume()的调用。我们继续跟踪performLaunchActivity()。
在这里插入图片描述
上述代码在关键位置都加了注释。通过注释我们明白了Activity的创建以及onCreate()的调用都是在Instrumentation中完成的。这里需要注意一下Activtiy.attach()的调用时机,我们会在下文中用到。Instrumentation具体的代码如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值