一,前导知识:Activity的管理
Activity的管理是一个庞大又复杂的工作,其中涉及很多相关数据结构:
ActivityRecord:
TaskRecord:
ActivityStack:
ActivityDisplay:
ActivityStackSupervisor:
ProcessRecord:
图中的方框可以理解为包含关系,譬如一个TaskRecord中包含多个ActivityRecord,连线可以理解为等价关系,譬如一个ActivityRecord会被TaskRecord和ProcessRecord引用。
-ActivityRecord是Activity管理的最小单位,它对应着一个用户界面;
-TaskRecord是一个栈式管理结构,每一个TaskRecord都可能存在一个或多个ActivityRecord,栈顶的ActivityRecord表示当前可见的界面;
-ActivityStack也是一个栈式管理结构,每一个ActivityStack都可能存在一个或多个TaskRecord,栈顶的TaskRecord表示当前可见的任务;
-ActivityStackSupervisor管理着多个ActivityStack,但当前只会又一个获取焦点的ActivityStack;
-ProcessRecord记录着属于一个进程的所有ActivityRecord,运行在不同的TaskRecord中的ActivityRecord可能是属于同一个ProcessRecord。
ActivityRecord
ActivityRecord是AMS调度Activity的最小单位,它只需要记录AndroidManifest.xml中所定义Activity的静态特征,同时也需要记录Activity在被调度时的状态变化,因此ActivityRecord这个类的属性较多而行为较少,其行为大多时一些用于判定和更新当前ActivityRecord状态的函数。
- 每次需要启动一个新的Activity时,都会构建一个ActivityRecord对象
TaskRecord
TaskRecord(任务栈)的职责是管理多个ActivityRecord,启动Activity时需要找到Activity的宿主任务,如果不存在则需要新建一个,所有的ActivityRecord都必须有宿主。TaskRecord是一对多的关系,TaskRecord的属性中包含了ActivityRecord的数组;同时TaskRecord还需要维护任务栈本身的状态。 - 启动一个Activity时,通常需要将ActivityRecord压入任务栈顶;
- 当待显示的Activity压入任务栈后,就需要设置栈顶ActivityRecord的状态,这时候,会调用topRunningActivityLocked()函数来获取栈顶的元素;
ActivityStack
ActivityStack的职责是管理多个任务战(TaskRecord),它也是一个栈式结构,栈中的元素就是TaskRecord,每个Activity在特定的时刻都会有一个状态,譬如显示、销毁等,在应用进程看来,这些状态的变化就是在执行Activity的生命周期函数;在系统进程看来,这些状态的变化都需要经过ActivityStack来驱动。Activity的状态是通过ActivityState这个枚举类来定义的:
Enum ActivityState{
INITIALIZING, RESUMED, PAUSING, PAUSED, STOPPING,
STOPPED, FINISHING, DESTROYING, DESTROYED
}
Activity状态的变迁,不仅仅是给ActivityRecord.state赋一个状态值那么简单,ActivityStack要对栈进行调整:之前的Activity要销毁或者挪到后台,待显示的Activity要挪到栈顶,这一调整,涉及到的工作就多了。
ActivityDisplay
Android支持多屏显示,在不同的显示设备上可以有不同的ActivityStack。所有的ActivityStack都是通过ActivityStackSupervisor管理起来的。 在ActivityStackSupervisor内部,设计了ActivityDisplay这个内部类,它对应到一个显示设备,默认的显示设备是手机屏幕。 ActivityStackSupervisor间接通过ActivityDisplay来维护多个ActivityStack的状态。 ActivityStack有一个属性是mStacks,当mStacks不为空时,表示ActivityStack已经绑定到了显示设备, 其实ActivityStack.mStacks只是一个副本,真正的对象在ActivityDisplay中。
ActivityContainer
在ActivityStackSupervisor中,还专门设计了内部类ActivityContainer,该类是对ActivityStack的封装,相当于是开了个后门,可以通过命令对ActivityStack进行读写操作,方便开发和调试。
ActivityStackSupervisor
ActivityStackSupervisor的职责是管理多个ActivityStack,里面有很多与ActivityStack功能类似的行为,不过都是针对ActivityStack进行操作。
ProcessRecord
AMS采用ProcessRecord这个数据结构来维护进程运行时的状态信息,当进程创建时(无论是系统进程还是用户进程),就会通过AMS初始化一个ProcessRecord。ProcessRecord有“激活(Active)”和“非激活(Inactive)”两种状态,只有将ProcessRecord绑定到一个实际进程的时候,才是激活状态。 绑定成功后,thread属性就被赋值,表示ProcessRecord已经激活。 激活后,AMS就可以通过这个接口完成对应用进程的管理,譬如启动Activity、派发广播等。
关联关系
ActivityThread:应用的入口类,系统通过调用main函数,开启消息循环队列,ActivityThread所在的线程被称为应用的主线程(UI线程)
Instrumentation:工具类,它用来监控应用程序和系统的交互,包装了 ActivityManagerService 的调用,一些插件化方案就是通过 hook 该类实现的。
ActivityStarter:Activity 启动的工具类,处理启动 Activity 的各种 flag。
ApplicationThread:ApplicationThread是ActivityThread的私有内部类,实现了IBinder接口,用于ActivityThread和ActivityManagerService的所在进程间通信。
二,Android应用的启动流程
流程概述:
从用户手指触摸点击桌面图标到Activity启动
1, 点击桌面APP,发起进程就是Launcher所在的进程,启动远程进程,利用Binder发送消息给SystemServer进程;
2, 在SystemServer中,启动进程的操作会先调用startProcessLocked()方法,该方法内部调用Process.start(),而后通过socket通信告知Zygote进程fork子进程,即APP进程。进程创建后将ActivityThread加载进去,执行ActivityThread.main()方法;
3, 在APP进程中,main()方法会实例化ActivityThread,同时创建ApplicationThread,Looper、Handler对象,调用attach方法进行Binder通信,将thread信息告知ActivityManagerService,接着Looper启动循环;
4, 回到SystemServer中,在attachApplication()中调用bindApplication()和attachApplicationLocked()方法:
bindApplication()方法中最终走到了ActivityThread.handleBindApplication(),创建Application对象,然后绑定Context,创建完Application对象后便是调用mInstrumentation.callApplicationOnCreate()执行Application.onCreate()生命周期;
attachApplicationLocked()方法最终走到了ActivityThread.handLaunchActivity(), 创建Activity对象,然后调用activity.attach()方法,再调用mInstrumentation.callActivityOnCreate()执行Activity.onCreate()生命周期。
详细流程:
1,用户点击APP图标,Launcher捕捉点击事件,调用Activity.startActivity(),里面调用Instrumentation,Instrumentation通过Binder通信发送消息给SystemServer进程
Activity.Java
1.@Override
2. public void startActivity(Intent intent) {
3. this.startActivity(intent, null);
4. }
5. @Override
6. public void startActivity(Intent intent, @Nullable Bundle options) {
7. if (options != null) {
8. startActivityForResult(intent, -1, options);
9. } else {
10. // Note we want to go through this call for compatibility with
11. // applications that may have overridden the method.
12. startActivityForResult(intent, -1);
13. }
14. }
15. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
16. @Nullable Bundle options) {
17. if (mParent == null) {
18. options = transferSpringboardActivityOptions(options);
19. Instrumentation.ActivityResult ar =
20. mInstrumentation.execStartActivity(
21. this, mMainThread.getApplicationThread(), mToken, this,
22. intent, requestCode, options);
23. ···
24. } else {
25. ···
26. }
27. }
2,AMS接到消息后完成一些初始化操作:一些调用链如下:
AMS -> ActivityStarter - > ActivityStackSuperviser -> ActivityStack -> ActivityStackSupervisor -> AMS,然后需要判断要启动的APP进程是否已经存在,存在(热启动)则通知进程启动Activity,不存在(冷启动)就先将进程创建出来。
1.void startSpecificActivityLocked(ActivityRecord r,
2. boolean andResume, boolean checkConfig) {
3. ···
4. if (app != null && app.thread != null) {
5. try {
6. ···
7. // 如果进程已存在,则通知进程启动组件
8. realStartActivityLocked(r, app, andResume, checkConfig);
9. return;
10. } catch (RemoteException e) {
11. ···
12. }
13. }
14. // 否则先将进程创建出来
15. mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
16. "activity", r.intent.getComponent(), false, false, true);
17. }
3,在进程尚未创建的情况,需要调用Process.start()来启动进程,接着AMS通过socket通信告知Zygote进程fork子进程,即APP进程。创建后将ActivityThread加载进去,执行ActivityThread.main()方法,实例化ActivityThread,同时创建ApplicationThread,Looper,Handler对象,调用ActivityThread.attach()进行Binder通信,接着Looper启动循环;
ActivityThread.java
1.public static void main(String[] args) {
2. ···
3. Looper.prepareMainLooper();
4.
5. ActivityThread thread = new ActivityThread();
6. thread.attach(false);
7.
8. if (sMainThreadHandler == null) {
9. sMainThreadHandler = thread.getHandler();
10. }
11. ···
12. Looper.loop();
13. ···
14. }
15.
16.
17. private void attach(boolean system) {
18. ···
19. if (!system) {
20. ···
21. final IActivityManager mgr = ActivityManager.getService();
22. try {
23. mgr.attachApplication(mAppThread);
24. } catch (RemoteException ex) {
25. throw ex.rethrowFromSystemServer();
26. }
27. ···
28. } else {
29. ···
30. }
31. ···
32. }
4,回到SystemServer进程中,AMS.attachApplication()方法内部调用了thread,bindApplication()和mStackSupervisor.attachApplicationLocked()这两个方法。
- thread.bindApplication()方法调用,最终走到了ActivityThread.handleBindApplication(),进而创建Application对象,然后调用Application.attach()来绑定Context,创建完Application对象后便是调用mInstrumentation.callApplicationOnCreate()执行Application.onCreate()生命周期。
ActivityThread.java
1.private void handleBindApplication(AppBindData data) {
2. ···
3. try {
4. // 创建 Application 实例
5. Application app = data.info.makeApplication(data.restrictedBackupMode, null);
6. mInitialApplication = app;
7. ···
8. try {
9. mInstrumentation.callApplicationOnCreate(app);
10. } catch (Exception e) {
11. ···
12. }
13. } finally {
14. ···
15. }
16. ···
17.}
mStackSupervisor.attachApplicationLocked()方法最终调用到ActivityThread.handleLaunchActivity(),进而创建Activity对象,然后调用activity.attach()方法,再调用mInstrumentation.callActivityOnCreate()执行Activity.onCreate()生命周期。