应用的启动(这里说的是冷启动)流程涉及到四个进程,所以大的方面是讲四个进程及其作用,然后分别讲这四个进程具体做了什么事情。
四个进程
Android应用的启动涉及了Launcher进程、ActivityManagerService(AMS)进程、Zygote进程及需要启动的应用进程。
1、Launch应用进程
Launcher是一个系统应用,因此是一个独立进程,在系统启动之后拉起Launcher进程展示桌面。这个过程中,Launcher会通过PMS获取已安装的应用的信息,然后在桌面给这些应用一一分配展示位置。
2、AMS进程
AMS进程主要负责管理Android的四大组件,包括四大组件对应进程的启动、四大组件生命周期的调用等等。
3、Zygote进程
Zygote进程负责创建新的应用进程
4、应用进程
这个就是需要启动的应用所运行的进程。
详细介绍 https://juejin.cn/post/6847902222294990862#heading-2
Launcher进程
1、当点击Luncher上的图标时,Launcher获取这个图标对应的应用信息,包括进程id、这个应用的MainActivity信息,并把这些信息保存在一个Intent里面。
2、接着调用Luncher的startActivitySafety方法。在这里会给Intent加入一个标志:FLAG_ACTIVITY_NEW_TASK。表示接下来启动的这个Activity是需要在新的Activity栈中启动。
3、接着调用Activity类的startActivity(参数1是Intent,参数2根据是否需要启动动画设置的Bundle),在这个方法里调用startActivityForResult方法(参数是前两个参数,参数3是-1,表示Launcher不需要知道应用启动的结果)。接下来就和上面普通Activity启动的发起 过程一致
4、接着调用Instrumentation的execStartActivity方法(可以hook启动),在这个方法中通过AMS的远程代理对象IActivityManager调用AMS的startActivity方法(可以hook启动)。
execStartActivity中会校验activity是否可用,checkStartActivityResult(result, intent),不可用就抛错
AMS进程(现在有ATMS-> ActivityTaskManagerService)
5、AMS进程接收发到Launcher进程发起的启动新应用的请求,调用startActivity方法。在这里会调用多个方法,最终通过对象池的方式创建一个ActivityStarter对象。
6、接着调用ActivityStarter的execute方法,然后调用startActivityMayWait方法。在这个方法中,收集需要启动的应用的信息,包括进程信息,MainActivity信息,然后调用另一个startActivity方法。
7、创建一个ProcessRecord和一个ActivityRecord的对象,分别存储进程信息和Activity的信息,再调用另一个startActivity方法,这个新的startActivity方法调用了startActivityUnChecked方法。
8、startActivityUnchecked方法检查需要启动的Activity的启动模式及检查是否需要重新创建一个Activity栈。同时通知Launcher进入paused状态。处理完一系列的栈操作之后,在
ActivityStackSupervisor中的startSpecificActivity方法判断 !!!!!应用进程IApplicationThread是否启动,有应用进程就启动activity(普通activity),没有就去创建进程(然后再启动根activity) realStartActivityLocked
9、AMS以Socket方式通知Zygote需要启动一个新进程。 Process.start() -> ZYGOTE_PROCESS.start
Zygote进程
10、负责fork出一个新的进程,及应用进程
应用进程
11、进程启动之后,先创建一个Binder线程池,然后反射调用ActivityThread的main方法
12、在main方法中,首先创建应用程序主线程的Looper及MessageQueue对象,接着调用attach方法,告知AMS应用程序启动成功。然后调用主线程的Looper的loop方法启动消息循环。
13、在attach方法中。通过AMS的远程代理对象,调用attachApplication把一个ApplicationThread对象传递到AMS。这个ApplicationThread对象是一个Binder对象,供AMS与应用程序联系使用。
AMS进程
14、AMS接收到应用程序的启动完成通知,调用attachApplicationLocked方法
然后查找这个应用进程的ContentProvider,通知应用程序启动这些provider。
调用IApplicationThread的bindApplication方法,IPC操作,创建绑定Application
通过makeActive方法赋值IApplicationThread,即验证了上面的猜测(创建进程后赋值);
通过ATMS的attachApplication, 通知ActivityStackSupervisor.realStartActivityLocked启动根**activity** (普通**activity**启动也是realStartActivityLocked)
接着再调用的ApplicationThread对象的bindApplication方法,通知应用程序创建一个Application。
应用程序进程 ApplicationThread
15、ApplicationThread的bindApplication会sendMessage(H.BIND_APPLICATION, data),转移到了ActivityThread的handleBindApplication方法(从Binder线程池转移到主线程), 创建Application,内部会调用attach方法,attach内部会调用attachBaseContext方法,接着才是onCreate方法
启动activity realStartActivityLocked
16、调用ApplicationThread的scheduleTransaction方法->ActivityThread. scheduleTransaction->sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction)->调用了mH.sendMessage(msg)
mH是在创建ActivityThread实例时赋值的,是自定义[Handler](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Fhfy8971613%2Farticle%2Fdetails%2F103881609)子类H的实例,也就是在ActivityThread的main方法中,并且初始化是已经主线程已经有了mainLooper,所以,使用这个**mH**来**sendMessage**就把消息发送到了主线程
17、EXECUTE_TRANSACTION ->mTransactionExecutor.execute(transaction) ->
executeCallbacks()
handleLaunchActivity-> performLaunchActivity
1,从ActivityClientRecord获取待启动的Activity的组件信息
2,通过mInstrumentation.newActivity方法使用类加载器创建activity实例
3,通过LoadedApk的makeApplication方法创建Application对象,内部也是通过mInstrumentation使用类加载器,创建后就调用了instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法。
4,创建ContextImpl对象并通过activity.attach方法对重要数据初始化,关联了Context的具体实现ContextImpl,attach方法内部还完成了window创建,这样Window接收到外部事件后就能传递给Activity了。
5,调用Activity的onCreate方法,是通过 mInstrumentation.callActivityOnCreate方法完成。
executeLifecycleState():
handleResumeActivity-> performResumeActivity
调用生命周期:通过performResumeActivity方法,内部调用生命周期onStart、onResume方法
设置视图可见:通过activity.makeVisible方法,添加[window](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Fhfy8971613%2Farticle%2Fdetails%2F103241153)、设置可见。(所以视图的真正可见是在onResume方法之后)