启动Activity的方式
Activity有2种启动的方式,一种是在Launcher界面点击应用的图标、另一种是在应用中通过Intent进行跳转。我们主要介绍与后者相关的启动流程。
1 | Intent intent = new Intent(this, TestActivity.class); |
从Activity入手
1 |
|
我们看到最终都会进入startActivityForResult()
方法。我们跟进去看看:
1 | public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { |
继续进入Instrumentation
类,看看execStartActivity
方法:
1 | //Instrumentation类 |
上面的代码可以看出,启动Activity真正的实现交给了ActivityManagerNative.getDefault()
的startActivity方法来完成。然后启动之后通过checkStartActivityResult(result, intent);
来检查Activity的启动结果(比如Activity没有在AndroidManifest.xml中注册就throw ActivityNotFoundException
的异常等)。
我们来着重看下这个ActivityManagerNative
。
ActivityManagerNative是什么?
ActivityManagerNative
比较特殊,从下面的定义可以看到它就是一个Binder对象,并实现了IActivityManager
接口。而它的getDefault()
方法其实就是通过asInterface(IBinder obj)
方法构建的ActivityManagerProxy(obj)
单例。
1 | public abstract class ActivityManagerNative extends Binder implements IActivityManager |
而ActivityManagerNative.getDefault()
实际上是个ActivityManagerService
(简称AMS),因此Activity的启动任务其实最后交给了AMS中,
ActivityManagerService(AMS)
看AMS的startActivity()
方法
1 | //ActivityManagerService类 |
可以看出,Activity启动任务被AMS转交给了ActivityStackSupervisor
的startActivityMayWait
方法。
1 | //ActivityStackSupervisor类 |
ActivityStackSupervisor
类中的startActivityMayWait
方法调用startActivityLocked()
继续执行,而startActivityLocked()
方法中又会调用startActivityUncheckedLocked()
方法,然后会调用resumeTopActivitiesLocked()
方法:
1 | //ActivityStackSupervisor类 |
上面代码能看到,最后启动过程从ActivityStackSupervisor
类交给了ActivityStack
类。
跟进它的resumeTopActivityLocked
方法:
1 | /** |
继续看看resumeTopActivityInnerLocked()
方法
1 |
|
又返回ActivityStackSupervisor类
1 | //ActivityStackSupervisor类 |
上面的startSpecificActivityLocked()
方法,首先判断需要启动的Activity所在进程和app是否已经存在。若存在,直接拿着该进行信息去启动该Activity,否则准备创建该进程。
我们简单先看下创建该App进程的方法startProcessLocked()
,位于ActivityManagerService类中:
1 | //ActivityManagerService类中 |
我们可以看到这个方法就是使用Process.start()
,并通过Socket连接的方式孵化新建了一个Zygote进程,完成了ActivityThread的创建,之后就会执行ActivityThread的main()
方法。
接着上面,App进程如果存在就会直接调用realStartActivityLocked()
方法:
1 | //ActivityStackSupervisor类中 |
上面的调用了app.thread
的scheduleLaunchActivity()
方法,app的类型是ProcessRecord
类,它的thread成员变量定义如下,是一个IApplicationThread
对象:
1 | /** |
而IApplicationThread
的声明如下:
1 | /** |
可以看到IApplicationThread
它继承了IInterface接口,是一个Binder类型接口。里面包含了大量的启动、停止Activity的接口,启动、停止Service的接口。那么它的实现者到底是谁呢?答案就是ActivityThread
类里的内部类ApplicationThread
,我们去看看它的定义:
1 | private class ApplicationThread extends ApplicationThreadNative {...} |
可以看到,ApplicationThread
类继承自ApplicationThreadNative
,而ApplicationThreadNative
是一个Binder对象并且实现了IApplicationThread
接口。
而且在ApplicationThreadNative
类的内部有一个ApplicationThreadProxy
代理类。
1 | public abstract class ApplicationThreadNative extends Binder |
也就是说,按照上面的流程,最终从AMS回调到了ApplicationThread
中,我们看看ApplicationThread
类的scheduleLaunchActivity()
方法:
1 | //位于ActivityThread类中的内部类ApplicationThread类中 |
可以看到,scheduleLaunchActivity
方法就是发送了一个启动Activity的Message交给H这个Handler,这个Handler定义如下:
1 | private class H extends Handler { |
H这个Handler对LAUNCH_ACTIVITY
的处理就是调用了handleLaunchActivity
方法:
1 | //ActivityThread类中 |
最终:
- 通过ActivityThread的
performLaunchActivity()
方法完成了Activity的创建和启动过程; - 通过
handleResumeActivity()
方法调用了这个Activity的onResume()
生命周期方法。
performLaunchActivity()
方法
performLaunchActivity()
方法主要完成了Activity的初始化任务,根据注释大致可以分为四步:
1 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
总结上面的performLaunchActivity()
方法,主要完成了如下工作:
- 从ActivityClientRecord中读取Activity的组件信息
- 通过
mInstrumentation.newActivity()
方法创建Activity对象 - 通过LoadApk的
makeApplication()
方法创建Application对象 - 创建
ContextImpl
对象并调用Activity的attach()
方法完成初始化 - 通过Instrumentation的
callActivityOnCreate
方法调用Activity的onCreate()
方法
我们跟进一下第二步的Instrumentation
类的newActivity()
方法,很简单,就是使用类加载器创建了Activity对象:
1 | //Instrumentation类 |
第三步:通过LoadApk的makeApplication()
方法创建Application对象:
1 | //LoadApk类 |
跟进去Instrumentation类的newApplication()
方法看看:
1 | //Instrumentation类 |
它通过类加载器创建了Application的对象,当Application对象创建完毕之后,系统会通过Instrumentation类的callApplicationOnCreate()
方法来调用Application的onCreate()
方法。最后通过app.attach()
调用了我们熟悉的Application的attachBaseContext()
方法。
handleResumeActivity()
方法流程
1 | //ActivityThread类 |
接着看performResumeActivity()
方法:
1 | //ActivityThread类 |
ActivityThread类中的performResumeActivity()
方法调用了Activity类的performResume()
方法:
1 | //Activity类 |
Instrumentation类中的callActivityOnResume
方法
1 | /** Instrumentation类 |
应用的主要启动流程
关于 App 启动流程的文章很多,文章底部有一些启动流程相关的参考文章,这里只列出大致流程如下:
- 通过 Launcher 启动应用时,点击应用图标后,Launcher 调用
startActivity()
启动应用。 - Launcher Activity 最终调用
Instrumentation
的execStartActivity
来启动应用。 Instrumentation
调用ActivityManagerProxy
(ActivityManagerService
在应用进程的一个代理对象) 对象的startActivity
方法启动 Activity。- 到目前为止所有过程都在 Launcher 进程里面执行,接下来
ActivityManagerProxy
对象跨进程调用ActivityManagerService
(运行在system_server
进程)的startActivity
方法启动应用。 ActivityManagerService
的startActivity
方法经过一系列调用,最后调用zygoteSendArgsAndGetResult
通过socket
发送给zygote
进程,zygote
进程会孵化出新的应用进程。zygote
进程孵化出新的应用进程后,会执行ActivityThread
类的main()
方法。在该方法里会先准备好Looper
和消息队列,然后调用attach()
方法将应用进程绑定到ActivityManagerService
,然后进入loop
循环,不断地读取消息队列里的消息,并分发消息。ActivityManagerService
保存应用进程的一个代理对象,然后ActivityManagerService
通过代理对象通知应用进程创建入口 Activity 的实例,并执行它的生命周期函数。
总结过程就是:用户在 Launcher
程序里点击应用图标时,会通知 ActivityManagerService
启动应用的入口 Activity, ActivityManagerService
发现这个应用还未启动,则会通知 Zygote
进程孵化出应用进程,然后在这个应用进程里执行 ActivityThread
的 main() 方法。应用进程接下来通知ActivityManagerService
应用进程已启动,ActivityManagerService
保存应用进程的一个代理对象,这样ActivityManagerService
可以通过这个代理对象控制应用进程,然后 ActivityManagerService 通知应用进程创建入口 Activity 的实例,并执行它的生命周期函数。
到这里,我们大概理解一下这几个相关类的定位
(一)ActivityManagerService:(ActivityManagerNative)是核心管理类,负责组件的管理,在这里主要与ActivityStackSupervisor通信。
(二)ActivityStackSupervisor:管理整个手机任务栈,即管理着ActivityStack。
(三)ActivityStack:是Activity的栈,即任务栈,从中可以获取需要进行操作的ActivityRecord,并且可以对任务的进程进行操作。
(四)ActivityThread:是安卓java应用层的入口函数类,它会执行具体对Activity的操作,并将结果通知给ActivityManagerService。