应用进程启动
当用户从桌面点击一个应用图标时,该应用就会启动并显示主Activity,即在AndroidManifest中标注如下过滤器的Activity:
里面的category中涉及到LAUNCHER。这个其实和Laucher进程有关,这是一个桌面进程。所以从桌面点击图标到应用启动显示的页面的过程,其实就是从一个应用启动到另一个应用的过程。
总体流程大致如下图所示:
① 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求。
② system_server进程接收到请求后,向zygote进程发送创建进程的请求。
system_server中的 AMS 发送socket请求,openZygoteSocketIfNeeded函数中打开本地socket客户端连接到zygote进程的socket服务端;
③ Zygote进程fork出新的子进程,即App进程。 ④ App进程,通过Binder IPC向sytem_server进程发起attachApplication请求。 ⑤ system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求。 ⑥ App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息。 ⑦ 主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate()等方法。
JNI调用启动进程的binder线程池(注意应用进程的binder线程池资源是自己创建的并非从zygote父进程继承的);通过反射创建ActivityThread对象并调用其“main”入口方法。
⑧ 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。
7-8步中面试官可能会让你 详细介绍下 应用创建到显示 Application 在新进程⾥创建ActivityThread对象,新创建的进程含有应⽤的主线程,在主线程⾥开启Looper消息循环,开始处理创建Activity。 ActivityThread被反射创建,调用其”main” 方法,利⽤ClassLoader去加载Activity、创建Activity实例,并回调Activity的onCreate()⽅法,这样便完成了Activity的启动
public static void main(String[] args){ ... Looper.prepareMainLooper(); //初始化Looper ... ActivityThread thread = new ActivityThread(); //实例化一个ActivityThread thread.attach(false); //这个方法最后就是为了发送出创建Application的消息 ... Looper.loop(); //主线程进入无限循环状态,等待接收消息}thread.attach(false) -> ApplicationThread的信息终于传递到了AMS中 -> 调用了自己的bindApplication()方法,发出初始化Applicationd的消息:
bindApplication()函数就是AMS的ApplicationThread的代理,通过Binder进程间通信调用app进程的ApplicationThread的bindApplication()方法
public final void bindApplication(String processName, ApplicationInfo appInfo, Listproviders, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings){ ... sendMessage(H.BIND_APPLICATION, data);}还记不记得最开始main函数创建的Looper。而ActivityThread中还存在一个该Looper的处理对象Hander H。从传送的参数H.BIND_APPLICATION可以看到,这个消息就是发送给这个H来处理的。 一旦H接收到这个消息就开始创建Application了
H 就是Handler
->handleBindApplication有个类Instrumentation,它在创建Application类之前进行实例化。它能够允许你监视应用程序和系统的所有交互最终Apllication的创建,Activity的创建,以及生命周期都会经过这个对象去执行 -> Instrumentation调用的方法callApplicationOnCreate -> 调用的方法makeApplication 反射找到了Application的类名。其次创建了Application的ContextImpl ,ContextImpl 其实Application的Context具体执行的类,我们平时调用的Context有关的方法最后其实都是调用了ContextImpl 的对应方法,这里不展开讲了。之后就是通过刚才说的mInstrumentation来调用newApplication 至此终于将Application创建出来了。
创建及启动Activity -> AMS通过ApplicationThread的代理调用bindApplication() -> 此时AMS的对应线程会接着往下执行代码以同样的方法通过ApplicationThread的代理向ApplicationThread发起启动主Activity的请求, 并且在ApplicationThread中向H发送一条LAUNCH_ACTIVITY的消息。然后H就开始了初始化Activity。 收到LAUNCH_ACTIVITY后H会调用handleLaunchActivity():
-> performLaunchActivity
-> mInstrumentation.newActivity
-> 通过反射实例化了Activity
performLaunchActivity() 创建了Activity后 将之前创建出来的Application和Activity关联
成功调用了Activity的onCreate()方法。其实之后的onStart(),onResume()等生命周期的方法也时类似这样调用的
整体示意图如下