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();

android 如何启动launcher 安卓launcher启动器_java


启动的服务有以下:包括我们常见的,AMS、PMS、WMS…

android 如何启动launcher 安卓launcher启动器_android_02


android 如何启动launcher 安卓launcher启动器_java_03


接下来就需要初始化这些服务:

android 如何启动launcher 安卓launcher启动器_android_04


android 如何启动launcher 安卓launcher启动器_java_05


从注释可以了解到,现在所有的服务都已经启动好了,可以告诉ActivityManager已经ok了。可以开始launching系统第一个application了(initial:最开始的,第一个的)。

调用 frameworks /base /services /core /java /com /android /server /am /ActivityManagerService.systemReady() 进行启动任务。

跟进去

android 如何启动launcher 安卓launcher启动器_生命周期_06


mAtmInternal是什么呢?

frameworks /base /services /core /java /com /android /server /wm /ActivityTaskManagerInternal.java,发现它是一个抽象类,真正的实现类是在 ==frameworks /base /services /core /java /com /android /server /wm /ActivityTaskManagerService.LocalService ==

android 如何启动launcher 安卓launcher启动器_android_07


android 如何启动launcher 安卓launcher启动器_生命周期_08


mRootActivityContainer就是 frameworks /base /services /core /java /com /android /server /wm /RootActivityContainer.java

android 如何启动launcher 安卓launcher启动器_生命周期_09


跟进去发现,会先调用ActivityTaskManagerService的getHomeIntent(),intent.addCategory(Intent.CATEGORY_HOME); 看到这里熟悉了吗。

android 如何启动launcher 安卓launcher启动器_java_10


然后会调用ActivityTaskManagerService的getActivityStartController()获取 frameworks /base /services /core /java /com /android /server /wm /ActivityStartController对象,调用ActivityStartController的startHomeActivity()方法。

android 如何启动launcher 安卓launcher启动器_android_11


发现其调用的是 frameworks /base /services /core /java /com /android /server /wm /ActivityStackSupervisor 的scheduleResumeTopActivities()方法

android 如何启动launcher 安卓launcher启动器_生命周期_12


发现是通过Handler发送了一个消息进行处理:

android 如何启动launcher 安卓launcher启动器_java_13


调用RootActivityContainer的resumeFocusedStacksTopActivities()方法,

android 如何启动launcher 安卓launcher启动器_java_14


最后再调用 frameworks /base /services /core /java /com /android /server /wm /ActivityStack的 resumeTopActivityUncheckedLocked()方法

android 如何启动launcher 安卓launcher启动器_生命周期_15


里面会调用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退出执行。

android 如何启动launcher 安卓launcher启动器_生命周期_16


到这里大家是不是纳闷了,resumeTopActivityInnerLocked都退出执行了,怎么resume Activity B呢?

往下看

在startPausingLocked()方法里,将mResumedActivity赋值给mPausingActivity,并设置状态为PAUSING,再将mResumedActivity置为null。之后通过IApplicationThread通知对应APP进程执行pause操作(这里就是ActivityThread里的操作了,调度到APP进程)。

android 如何启动launcher 安卓launcher启动器_生命周期_17

当Activity pause执行完毕后,会调用ActivityStack的completePauseLocked()方法,里面会再次调用RootActivityContainer.resumeFocusedStacksTopActivities();

android 如何启动launcher 安卓launcher启动器_java_18


2.resume下一个Activity

此时判断mResumedActivity已经为null(在startPausingLocked中会置为null),因此不进行pause操作,继续往下执行

android 如何启动launcher 安卓launcher启动器_android_19

判断如果Activity所在进程存在且Activity之前启动过,则直接发送ResumeActivityItem请求通知APP进程进行resume

否则调用ActivityStackSupervisor的startSpecificActivityLocked方法继续执行。

android 如何启动launcher 安卓launcher启动器_android_20


该方法中判断目标APP进程若存在,则调用realStartActivityLocked方法继续进行启动流程,否则调用ActivityTaskManagerService.mH.sendMessage(msg)先启动目标进程

2.1 进程不存在

调用ActivityTaskManagerService.mH.sendMessage(msg)先启动目标进程

mH又是什么呢?

android 如何启动launcher 安卓launcher启动器_android_21


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方法

android 如何启动launcher 安卓launcher启动器_生命周期_22


android 如何启动launcher 安卓launcher启动器_java_23

内部又多次调用了startProcessLocked不同的重载方法,最后走到startProcess方法

android 如何启动launcher 安卓launcher启动器_android_24


跟进 frameworks /base /core /java /android/ os /Process.start()

android 如何启动launcher 安卓launcher启动器_java_25

ZYGOTE_PROCESS 就是 frameworks /base /core /java /android /os /ZygoteProcess.java,是用于保持与Zygote进程的通信状态,发送socket请求与Zygote进程通信。

ZYGOTE_PROCESS的start就不再跟进去了。我们只需要知道其内部:

  • Zygote通过fork创建了一个进程
  • 在新建的进程中创建Binder线程池(此进程就支持了Binder IPC)
  • 最终是通过反射获取到了ActivityThread类并执行了main方法

    调用了attach方法

android 如何启动launcher 安卓launcher启动器_android_26


这里请记住三个关键:
1、IActivityManager 是ActivityManagerService在客户端的代理,用于app进程与system_server进程通信
2、IActivityTaskManager 是ActivityTaskManagerService在客户端的代理,用于app进程与system_server进程通信
3、IApplicationThread是ApplicationThread在系统进程的代理,用于system_server进程与app进程通信

所以IActivityManager 的attachApplication方法,就是IPC的走到AMS的attachApplication方法了:

android 如何启动launcher 安卓launcher启动器_android_27

attachApplicationLocked方法很长,这里保留重要的几点:

android 如何启动launcher 安卓launcher启动器_java_28


AMS的attachApplicationLocked方法主要三件事:

1、调用IApplicationThread的bindApplication方法,IPC操作,创建绑定Application;

2、通过makeActive方法赋值IApplicationThread

3、通过ATMS启动 根activity

调用了mAtmInternal.attachApplication方法,mAtmInternal是ActivityTaskManagerInternal实例,具体实现是在ActivityTaskManagerService的内部类LocalService,去看看

android 如何启动launcher 安卓launcher启动器_android_29


mRootActivityContainer是RootActivityContainer实例,看下它的attachApplication方法:

android 如何启动launcher 安卓launcher启动器_java_30


遍历activity栈,此时理论上应该只有一个根activity,然后调用mStackSupervisor.realStartActivityLocked方法,看到这里我们知道了,这里就开始走下面分析的流程了。

2.2 进程存在

调用realStartActivityLocked方法继续进行启动流程

android 如何启动launcher 安卓launcher启动器_java_31


中间有段代码如上,通过 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方法如下:

android 如何启动launcher 安卓launcher启动器_android_32


就是调用 frameworks /base /core /java /android /app /servertransaction /ClientTransaction 的schedule方法,那就看看:

android 如何启动launcher 安卓launcher启动器_生命周期_33


mClient又是什么呢?

android 如何启动launcher 安卓launcher启动器_生命周期_34

android 如何启动launcher 安卓launcher启动器_android_35

很简单,就是调用IApplicationThread的scheduleTransaction方法。由于IApplicationThread是ApplicationThread在系统进程的代理,所以真正执行的地方就是 客户端的ApplicationThread中了。也就是说,Activity启动的操作又跨进程的还给了客户端>

那么ApplicationThread在哪呢?

它是 frameworks /base /core /java /android /app /ActivityThread 的内部类,它充当了ActivityThread和AMS沟通的一个桥梁的作用。

android 如何启动launcher 安卓launcher启动器_android_36

调用了ActivityThread的scheduleTransaction方法。

然后我们在ActivityThread找到scheduleTransaction方法,发现找不到,为什么呢?

android 如何启动launcher 安卓launcher启动器_android_37

发现ActivityThread继承ClientTransactionHandler ,子类没有,那就去父类里找。

android 如何启动launcher 安卓launcher启动器_java_38

使用sendMessage发送消息,参数是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:

android 如何启动launcher 安卓launcher启动器_android_39


sendMessage在父类里是抽象方法,具体实现在ActivityThread:

android 如何启动launcher 安卓launcher启动器_生命周期_40


最后调用了mH.sendMessage(msg),mH是个啥?这里的mH可不是我们之前提过的ActivityTaskManagerService.mH,而是ActivityThread自己本身的mH:

android 如何启动launcher 安卓launcher启动器_android_41

大家应该知道,ActivityThread初始化时候执行main方法,里面会初始化主线程的mainLooper:

android 如何启动launcher 安卓launcher启动器_生命周期_42

而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。

android 如何启动launcher 安卓launcher启动器_java_43


而TransactionExecutor的构造方法是在哪里实例化的呢,是在ActivityThread中:

android 如何启动launcher 安卓launcher启动器_java_44


所以TransactionExecutor中的ClientTransactionHandler其实就是ActivityThread。接下来会用到!好了,继续

android 如何启动launcher 安卓launcher启动器_java_45


android 如何启动launcher 安卓launcher启动器_java_46


继续跟进executeCallbacks方法:

android 如何启动launcher 安卓launcher启动器_java_47

遍历callbacks,调用 frameworks /base /core /java /android /app /servertransaction /ClientTransactionItem 的execute方法,而我们这里要关注的是ClientTransactionItem的子类 frameworks /base /core /java /android /app /servertransaction /LaunchActivityItem ,看下它的execute方法:

android 如何启动launcher 安卓launcher启动器_生命周期_48


里面调用了client.handleLaunchActivity方法,看到这里,大家是不是就恍然大悟了,原来client是ClientTransactionHandler的子类实例对象,即ActivityThread。那么这里的client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。

android 如何启动launcher 安卓launcher启动器_生命周期_49


继续往下跟:

android 如何启动launcher 安卓launcher启动器_android_50


看到这里,大家就豁然开朗了, 在这个方法里,会进行以下操作:

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方法:

android 如何启动launcher 安卓launcher启动器_生命周期_51


前面只说了通过clientTransaction.addCallback添加LaunchActivityItem实例,在注意下面接着调用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem实例,这里我们关注ResumeActivityItem

继续看处理ActivityThread.H.EXECUTE_TRANSACTION这个消息的处理,即TransactionExecutor的execute方法:

android 如何启动launcher 安卓launcher启动器_android_52


前面我们关注的是executeCallbacks方法,现在看看executeLifecycleState方法:

android 如何启动launcher 安卓launcher启动器_java_53


这里取出了ActivityLifecycleItem并且调用了它的execute方法,实际就是ResumeActivityItem的方法

经过上面分析实际是走到ActivityThread的handleResumeActivity方法:

android 如何启动launcher 安卓launcher启动器_android_54


android 如何启动launcher 安卓launcher启动器_android_55

handleResumeActivity主要做了以下事情:

1、调用生命周期:通过performResumeActivity方法,内部调用activity.performResume,调用生命周期onStart、onResume方法
2、添加视图、设置视图可见:将DecorView添加到Window,通过activity.makeVisible方法,设置可见,这里会再次检测试图是否被添加。(所以视图的真正可见是在onResume方法之后)

进入performResumeActivity方法:

调用了 frameworks /base /core /java /android /app /Activity.performResume方法:

android 如何启动launcher 安卓launcher启动器_生命周期_56


跟进去

android 如何启动launcher 安卓launcher启动器_java_57


到这里启动后的生命周期走完了。再看第二点,添加视图,设置视图可见。即wm.addView(decor, l)方法和activity.makeVisible()方法:

android 如何启动launcher 安卓launcher启动器_android_58

android 如何启动launcher 安卓launcher启动器_android_59

这里对于view的添加和绘制先不深究,具体请看 View的绘制入口源码分析

这里把activity的顶级布局mDecor通过windowManager.addView()方法,把视图添加到window,并设置mDecor可见。到这里视图是真正可见了。值得注意的是,视图的真正可见是在onResume方法之后的。

另外一点,Activity视图渲染到Window后,会设置window焦点变化,先走到DecorView的onWindowFocusChanged方法,最后是到Activity的onWindowFocusChanged方法,表示首帧绘制完成,此时Activity可交互。

好了,到这里就是真正创建完成且可见可交互了。

看到这里,我们就会想到,当开启一个Activity时,会是什么样的流程内,这里我们从startActivity来分析:

android 如何启动launcher 安卓launcher启动器_java_60


android 如何启动launcher 安卓launcher启动器_java_61


接着看下mInstrumentation.execStartActivity方法:

android 如何启动launcher 安卓launcher启动器_android_62


这里看到Activity的启动又跨进程的交给了ActivityTaskManagerService了。

跟进去

android 如何启动launcher 安卓launcher启动器_java_63


跟到startActivityAsUser中,通过getActivityStartController().obtainStarter方法获取ActivityStarter实例 然后调用一系列方法,最后的execute()方法是开始启动activity:

android 如何启动launcher 安卓launcher启动器_android_64

分了两种情况,不过 不论startActivityMayWait还是startActivity最终都是走到下面这个startActivity方法:

android 如何启动launcher 安卓launcher启动器_生命周期_65


里面又调用了startActivityUnchecked方法,之后调用RootActivityContainer的resumeFocusedStacksTopActivities方法。

android 如何启动launcher 安卓launcher启动器_android_66


看到这里我们知道了,这里就开始走上面分析过的流程了

嗯,到这里根activity的启动流程也分析完了。

我们发现,根activity的启动前 需要创建应用进程,然后走到ActivityThread的main方法,开启主线程循环,初始化并绑定Application、赋值IApplicationThread,最后真正的启动过程和普通Activity是一致的。

这里附上UML时序图:

android 如何启动launcher 安卓launcher启动器_生命周期_67