从App启动到Launcher页面启动的流程

应用进程启动流程

先放一张应用进程启动的流程图。

当 Launcher应用点击某个应用图标时,会发送消息给 AMS,启动这个应用的 Launcher Activity。假如此时这个应用还未启动,AMS 会给 Zygote进程发送请求,要求先创建进程。 Zygote进程 会 fork出 一个进程,同时会对进程做一些初始化工作。之后这个会对这个新创建的进程会 启动binder机制,之后会执行应用进程入口函数:ActivityThread#main(进程会有一个默认线程创建去执行本进程的代码,这个默认的进程称之为主进程)在应用程序入口函数会启动主线程消息队列的Looper循环,之后会报告 AMS,进程已经启动完成可以进行接下来工作了。AMS 收到消息后,给应用进程发送消息,应用进程收到消息会干两件事:1、创建Application实例。2、启动 Launcher Activity。

以上是整个启动流程,具体从 ActivityThread#main 入口之后干得事情,就以代码片段的形式贴出来,来捋一下上述过程。

基于安卓版本:26

ActivityThread#main

public static void main(String[] args) {
  Looper.prepareMainLooper();
  ActivityThread thread = new ActivityThread();
  thread.attach(false);
  Looper.loop();
  ...
}

ActivityThread#attach

private void attach(boolean system) {
  final IActivityManager mgr = ActivityManager.getService();
  mgr.attachApplication(mAppThread);    // 进行IPC通信,通知AMS
  ...
}

ActivityManagerService#attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
  ...
  thread.bindApplication(...);    // 1、回调ActivityThread
  ... 
  mStackSupervisor.attachApplicationLocked(app)  // 2、启动首页
}

attachApplicationLocked 这里会有两个步骤需要注意的:1、回调App进程去创建Application 2、启动Launcher Activity

先看第一步:回调App进程去创建Application

ApplicationThread#bindApplication

public final void bindApplication(...){
  ...
  sendMessage(H.BIND_APPLICATION, data);
}

因为通过Binder机制进行IPC调用时,方法都在Binder线程中运行。通过Handler机制,将消息发送给主线程去执行。之后会调用 handleBindApplication方法

ActivityThread#handleBindApplication

private void handleBindApplication(...){
  ...
  //创建Application对象,并回调attachBaseContext
  Application app = data.info.makeApplication(data.restrictedBackupMode, null);  
  //回调 onCreate
   mInstrumentation.callApplicationOnCreate(app);
}

LoadedApk#makeApplication

public Application makeApplication(...){
  ...
  // 创建上下文 Context
  ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
  // 创建Application。并调用 attach、attachBaseContext来设置 mBase
  app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
}

至此,Application创建完成,同时通过 attachBaseContext 给mBase 设置了Application上下文Context:ContextImpl,之后调用了 onCreate声明周期方法。

再第二步:启动Launcher Activity

ActivityStackSupervisor#attachApplicationLocked

boolean attachApplicationLocked(...){
  ...
  ActivityRecord hr = stack.topRunningActivityLocked();
  realStartActivityLocked(hr, app, true, true)
}

ActivityStackSupervisor#realStartActivityLocked

final boolean realStartActivityLocked(...){
  ...
  // IPC 调用app进程ApplicationThread 启动页面
  app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,...);
}

Application#scheduleLaunchActivity

public final void scheduleLaunchActivity(...){
  ...
  sendMessage(H.LAUNCH_ACTIVITY, r);
}

接收到 AMS 启动页面的消息后,通过Handler机制把消息发送给主线程去执行:handleLaunchActivity

ActivityThread#handleLaunchActivity

private void handleLaunchActivity(...) {
  ...
  // 创建Activity,并执行attach、onCreate方法回调
  Activity a = performLaunchActivity(r, customIntent);
  // 执行 onResume 方法回调
  handleResumeActivity(r.token, ...);
}

ActivityThread#performLaunchActivity

private Activity performLaunchActivity(...){
  ...
  // 创建Activity 对应上下文环境 Context
  ContextImpl appContext = createBaseContextForActivity(r);
  // 创建Activity
  activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
  // 调用attach方法,初始化工作,其中就有设置 mBase
  activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
  // 回调 onCreate方法
  mInstrumentation.callActivityOnCreate(activity, r.state);
}

ActivityThread#handleResumeActivity

private Activity handleResumeActivity(...){
  ...
  r = performResumeActivity(token, clearHide, reason);
}
public final ActivityClientRecord performResumeActivity(...){
  ...
  r.activity.performResume();  // 调用onResume 回调
}

至此,启动的页面 onCreate 、 onResume 都已执行完成。

之前会在进程创建时,启动Binder机制,具体怎么启动呢,配一张图:


Binder机制启动

整体的主进程启动流程如下:


你可能感兴趣的:(从App启动到Launcher页面启动的流程)