Launcher即桌面,是Android智能设备的窗口,用户使用最频繁的软件之一。Launhcer是Android所有应用的入口,也提供窗口小部件等功能
当然,Launcher本身就是一个APP,一个提供桌面的APP,我们也可以开发一款Launcher APP作为手机的桌面。Laucher有很多和普通APP不同的地方。
- Launcher是顶部APP,即任何应用返回后都是到Launcher,不能再继续返回;
- Launcher是所有应用的入口,可以管理应用;
- Launcher是Android系统启动后就要显示给用户的应用。
。
我们的手机一开机第一眼看见的就是Launcher,也就是说Launcher在开机的过程中就已经启动完成,下文,我们就来看看。
前面,我们已经讲过了 init进程 –> Zygote进程 –> SystemServer进程的启动流程,
在SystemServer的main方法中,启动了各个服务,其中包括 startOtherServices();
启动的服务有以下:包括我们常见的,AMS、PMS、WMS…
接下来就需要初始化这些服务:
从注释可以了解到,现在所有的服务都已经启动好了,可以告诉ActivityManager已经ok了。可以开始launching系统第一个application了(initial:最开始的,第一个的)。
调用 frameworks /base /services /core /java /com /android /server /am /ActivityManagerService.systemReady() 进行启动任务。
跟进去
mAtmInternal是什么呢?
是 frameworks /base /services /core /java /com /android /server /wm /ActivityTaskManagerInternal.java,发现它是一个抽象类,真正的实现类是在 ==frameworks /base /services /core /java /com /android /server /wm /ActivityTaskManagerService.LocalService ==
mRootActivityContainer就是 frameworks /base /services /core /java /com /android /server /wm /RootActivityContainer.java
跟进去发现,会先调用ActivityTaskManagerService的getHomeIntent(),intent.addCategory(Intent.CATEGORY_HOME); 看到这里熟悉了吗。
然后会调用ActivityTaskManagerService的getActivityStartController()获取 frameworks /base /services /core /java /com /android /server /wm /ActivityStartController对象,调用ActivityStartController的startHomeActivity()方法。
发现其调用的是 frameworks /base /services /core /java /com /android /server /wm /ActivityStackSupervisor 的scheduleResumeTopActivities()方法
发现是通过Handler发送了一个消息进行处理:
调用RootActivityContainer的resumeFocusedStacksTopActivities()方法,
最后再调用 frameworks /base /services /core /java /com /android /server /wm /ActivityStack的 resumeTopActivityUncheckedLocked()方法
里面会调用ActivityStack的resumeTopActivityInnerLocked()方法,
启动Activity的过程是将Activity置为顶层可见,称为resume top Activity。resumeTopActivityInnerLocked方法中逻辑较多,因此拆解成多步来看:
由Activity A启动Activity B,则需要先pause Activity A,之后才resume Activity B。
1.pause当前显示的Activity
mResumedActivity表示当前正在显示的Activity。例如Activity A启动Activity B,
则此时mResumedActivity即为Activity A。
mResumedActivity不为空,pause这个Activity。
此处进入startPausingLocked方法,若其中成功执行pause操作,则会返回true,使resumeTopActivityInnerLocked退出执行。
到这里大家是不是纳闷了,resumeTopActivityInnerLocked都退出执行了,怎么resume Activity B呢?
往下看
在startPausingLocked()方法里,将mResumedActivity赋值给mPausingActivity,并设置状态为PAUSING,再将mResumedActivity置为null。之后通过IApplicationThread通知对应APP进程执行pause操作(这里就是ActivityThread里的操作了,调度到APP进程)。
当Activity pause执行完毕后,会调用ActivityStack的completePauseLocked()方法,里面会再次调用RootActivityContainer.resumeFocusedStacksTopActivities();
2.resume下一个Activity
此时判断mResumedActivity已经为null(在startPausingLocked中会置为null),因此不进行pause操作,继续往下执行
判断如果Activity所在进程存在且Activity之前启动过,则直接发送ResumeActivityItem请求通知APP进程进行resume
否则调用ActivityStackSupervisor的startSpecificActivityLocked方法继续执行。
该方法中判断目标APP进程若存在,则调用realStartActivityLocked方法继续进行启动流程,否则调用ActivityTaskManagerService.mH.sendMessage(msg)先启动目标进程
2.1 进程不存在
调用ActivityTaskManagerService.mH.sendMessage(msg)先启动目标进程
mH又是什么呢?
Message第一个参数是ActivityManagerInternal::startProcess,而ActivityManagerInternal是抽象类,实现类是ActivityManagerService.LocalService,ActivityTaskManagerInternal 也是抽象类,它的实现类是ActivityTaskManagerService.LocalService。ActivityTaskManagerService相当于帮ActivityManagerService分担了部分工作。ActivityManagerService.LocalService的startProcess方法调用了ActivityManagerService的startProcessLocked方法,startProcessLocked方法内部又调用了 frameworks /base /services /core /java /com /android /server /am /ProcessList 的startProcessLocked方法
内部又多次调用了startProcessLocked不同的重载方法,最后走到startProcess方法
跟进 frameworks /base /core /java /android/ os /Process.start()
ZYGOTE_PROCESS 就是 frameworks /base /core /java /android /os /ZygoteProcess.java,是用于保持与Zygote进程的通信状态,发送socket请求与Zygote进程通信。
ZYGOTE_PROCESS的start就不再跟进去了。我们只需要知道其内部:
- Zygote通过fork创建了一个进程
- 在新建的进程中创建Binder线程池(此进程就支持了Binder IPC)
- 最终是通过反射获取到了ActivityThread类并执行了main方法
调用了attach方法
这里请记住三个关键:
1、IActivityManager 是ActivityManagerService在客户端的代理,用于app进程与system_server进程通信
2、IActivityTaskManager 是ActivityTaskManagerService在客户端的代理,用于app进程与system_server进程通信
3、IApplicationThread是ApplicationThread在系统进程的代理,用于system_server进程与app进程通信
所以IActivityManager 的attachApplication方法,就是IPC的走到AMS的attachApplication方法了:
attachApplicationLocked方法很长,这里保留重要的几点:
AMS的attachApplicationLocked方法主要三件事:
1、调用IApplicationThread的bindApplication方法,IPC操作,创建绑定Application;
2、通过makeActive方法赋值IApplicationThread
3、通过ATMS启动 根activity
调用了mAtmInternal.attachApplication方法,mAtmInternal是ActivityTaskManagerInternal实例,具体实现是在ActivityTaskManagerService的内部类LocalService,去看看
mRootActivityContainer是RootActivityContainer实例,看下它的attachApplication方法:
遍历activity栈,此时理论上应该只有一个根activity,然后调用mStackSupervisor.realStartActivityLocked方法,看到这里我们知道了,这里就开始走下面分析的流程了。
2.2 进程存在
调用realStartActivityLocked方法继续进行启动流程
中间有段代码如上,通过 ClientTransaction.obtain( proc.getThread(), r.appToken)获取了clientTransaction,其中参数proc.getThread()是IApplicationThread,就是ApplicationThread在系统进程的代理。
接着看,使用clientTransaction.addCallback添加了LaunchActivityItem实例。
我们从名字就能看出,它就是用来启动activity的。它是怎么发挥作用的呢?接着看
回到realStartActivityLocked方法,接着调用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),
mService是ActivityTaskManagerService,getLifecycleManager()方法获取的是 frameworks /base /services /core /java /com /android /server /wm /ClientLifecycleManager 实例,它的scheduleTransaction方法如下:
就是调用 frameworks /base /core /java /android /app /servertransaction /ClientTransaction 的schedule方法,那就看看:
mClient又是什么呢?
很简单,就是调用IApplicationThread的scheduleTransaction方法。由于IApplicationThread是ApplicationThread在系统进程的代理,所以真正执行的地方就是 客户端的ApplicationThread中了。也就是说,Activity启动的操作又跨进程的还给了客户端>
那么ApplicationThread在哪呢?
它是 frameworks /base /core /java /android /app /ActivityThread 的内部类,它充当了ActivityThread和AMS沟通的一个桥梁的作用。
调用了ActivityThread的scheduleTransaction方法。
然后我们在ActivityThread找到scheduleTransaction方法,发现找不到,为什么呢?
发现ActivityThread继承ClientTransactionHandler ,子类没有,那就去父类里找。
使用sendMessage发送消息,参数是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:
sendMessage在父类里是抽象方法,具体实现在ActivityThread:
最后调用了mH.sendMessage(msg),mH是个啥?这里的mH可不是我们之前提过的ActivityTaskManagerService.mH,而是ActivityThread自己本身的mH:
大家应该知道,ActivityThread初始化时候执行main方法,里面会初始化主线程的mainLooper:
而mH是在创建ActivityThread实例时赋值的,所以,使用这个mH来sendMessage就把消息发送到了主线程。
那么是从哪个线程发送的呢?那就要看看ApplicationThread的scheduleTransaction方法是执行在哪个线程了。根据IPC知识,我们知道,服务器的Binder方法运行在Binder的线程池中,也就是说系统进行跨进程调用ApplicationThread的scheduleTransaction就是执行在Binder的线程池中的了。
到这里,消息就在主线程处理了,那么是怎么处理Activity的启动的呢?接着看。我们找到ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,就在handleMessage方法的倒数第三个case(就在下面代码):取出ClientTransaction实例,调用 frameworks /base /core /java /android /app /servertransaction /TransactionExecutor 的execute方法,那就看看:
这里插一条重点,就是TransactionExecutor的构造方法,传入的参数是ClientTransactionHandler,大家前面知道了它是一个抽象类,具体实现子类是ActivityThread。
而TransactionExecutor的构造方法是在哪里实例化的呢,是在ActivityThread中:
所以TransactionExecutor中的ClientTransactionHandler其实就是ActivityThread。接下来会用到!好了,继续
继续跟进executeCallbacks方法:
遍历callbacks,调用 frameworks /base /core /java /android /app /servertransaction /ClientTransactionItem 的execute方法,而我们这里要关注的是ClientTransactionItem的子类 frameworks /base /core /java /android /app /servertransaction /LaunchActivityItem ,看下它的execute方法:
里面调用了client.handleLaunchActivity方法,看到这里,大家是不是就恍然大悟了,原来client是ClientTransactionHandler的子类实例对象,即ActivityThread。那么这里的client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。
继续往下跟:
看到这里,大家就豁然开朗了, 在这个方法里,会进行以下操作:
1、创建classLoader
2、通过Instrumentation.newActivity创建Activity实例
3、如果没有application就makeApplication
4、通过Instrumentation.callActivityOnCreate执行Activity的onCreate()方法
到这里Activity的onCreate方法执行完,那么onStart、onResume呢?
上面看到LaunchActivityItem,是用来启动Activity的,也就是走到Activity的onCreate,那么是不是有 "XXXActivityItem"呢? 有的:
- LaunchActivityItem 远程App端的onCreate生命周期事务
- ResumeActivityItem 远程App端的onResume生命周期事务
- PauseActivityItem 远程App端的onPause生命周期事务
- StopActivityItem 远程App端的onStop生命周期事务
- DestroyActivityItem 远程App端onDestroy生命周期事务
那么我们再来看看ResumeActivityItem吧。
我们再来重新看看在ActivityStackSupervisor的realStartActivityLocked方法:
前面只说了通过clientTransaction.addCallback添加LaunchActivityItem实例,在注意下面接着调用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem实例,这里我们关注ResumeActivityItem
继续看处理ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,即TransactionExecutor的execute方法:
前面我们关注的是executeCallbacks方法,现在看看executeLifecycleState方法:
这里取出了ActivityLifecycleItem并且调用了它的execute方法,实际就是ResumeActivityItem的方法
经过上面分析实际是走到ActivityThread的handleResumeActivity方法:
handleResumeActivity主要做了以下事情:
1、调用生命周期:通过performResumeActivity方法,内部调用activity.performResume,调用生命周期onStart、onResume方法
2、添加视图、设置视图可见:将DecorView添加到Window,通过activity.makeVisible方法,设置可见,这里会再次检测试图是否被添加。(所以视图的真正可见是在onResume方法之后)
进入performResumeActivity方法:
调用了 frameworks /base /core /java /android /app /Activity.performResume方法:
跟进去
到这里启动后的生命周期走完了。再看第二点,添加视图,设置视图可见。即wm.addView(decor, l)方法和activity.makeVisible()方法:
这里对于view的添加和绘制先不深究,具体请看 View的绘制入口源码分析。
这里把activity的顶级布局mDecor通过windowManager.addView()方法,把视图添加到window,并设置mDecor可见。到这里视图是真正可见了。值得注意的是,视图的真正可见是在onResume方法之后的。
另外一点,Activity视图渲染到Window后,会设置window焦点变化,先走到DecorView的onWindowFocusChanged方法,最后是到Activity的onWindowFocusChanged方法,表示首帧绘制完成,此时Activity可交互。
好了,到这里就是真正创建完成且可见可交互了。
看到这里,我们就会想到,当开启一个Activity时,会是什么样的流程内,这里我们从startActivity来分析:
接着看下mInstrumentation.execStartActivity方法:
这里看到Activity的启动又跨进程的交给了ActivityTaskManagerService了。
跟进去
跟到startActivityAsUser中,通过getActivityStartController().obtainStarter方法获取ActivityStarter实例 然后调用一系列方法,最后的execute()方法是开始启动activity:
分了两种情况,不过 不论startActivityMayWait还是startActivity最终都是走到下面这个startActivity方法:
里面又调用了startActivityUnchecked方法,之后调用RootActivityContainer的resumeFocusedStacksTopActivities方法。
看到这里我们知道了,这里就开始走上面分析过的流程了
嗯,到这里根activity的启动流程也分析完了。
我们发现,根activity的启动前 需要创建应用进程,然后走到ActivityThread的main方法,开启主线程循环,初始化并绑定Application、赋值IApplicationThread,最后真正的启动过程和普通Activity是一致的。
这里附上UML时序图: