欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

荐 Android 应用启动流程简单整理

程序员文章站 2022-05-21 14:11:13
Android 应用启动流程简单整理应用启动流程简单分为三个模块,其中最后由ActivityThread启动Activity是常见的面试高频问题,所以前面两个部分简单整理(有空再上源码分析),第三部分从源码分析,讲的比较详细。一.Launcher请求ActivityManageService点击图标,调用 launcher类 的 startActivitySafely 方法,其中调用了内部方法 startActivity,方法里设置了 intent.addFlags(Intent.FLAG_A...

Android 根Activity流程简单整理

应用启动流程简单分为三个模块,其中最后由ActivityThread启动Activity是常见的面试高频问题,所以前面两个部分简单整理(有空再上源码分析),第三部分从源码分析,讲的比较详细。

一.Launcher请求ActivityManageService

  1. 点击图标,调用 launcher类 的 startActivitySafely 方法,其中调用了内部方法 startActivity,
  2. 方法里设置了 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);这样根Activity会在新的任务栈中启动,然后调用了activity的 startActivity方法
  3. startActivity 又调用 startActivityForResult 方法
  4. startActivityForResult 中判断mParent 是否为空 ,因为是根Activity还没创建,所以会走为空的分支 ,调用 Instrumentation的 execStartActivity 方法(不为空 走startActivityFromChild 方法 这个方法最终还是调用 Instrumentation的 execStartActivity 方法 具体情况后续分析)
  5. 看到 nstrumentation的 execStartActivity 方法 ,首先会调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象(AMP),接着调用它的startActivity方法。
  6. AMP是 ActivityManagerNative 的内部类 ,startActivity方法,通过IBinder对象mRemote向AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用ActivityManagerNative的onTransact方法中执行,
  7. onTransact中会调用AMSstartActivity方法

荐
                                                        Android  应用启动流程简单整理

二.ActivityManageService到ApplicationThread的调用流程

  1. AMS的startActivity方法中return了startActivityAsUser方法:
  2. startActivityAsUser方法中又return了mActivityStarter的startActivityMayWait方法
  3. 又调用了startActivityLocked方法
  4. 接着又调用startActivityUnchecked方法:
  5. startActivityUnchecked方法中调用了ActivityStackSupervisor类型的mSupervisor的resumeFocusedStackTopActivityLocked方法
  6. 在注释1处又调用了ActivityStack类型mFocusedStack的resumeTopActivityUncheckedLocked方法:
  7. 紧接着查看ActivityStack的resumeTopActivityInnerLocked方法
  8. 最后运行 realStartActivityLocked方法 ,app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。最后调用了ApplicationThread的scheduleLaunchActivity方法

荐
                                                        Android  应用启动流程简单整理

三.ActivityThread启动Activity(重点来了)

ApplicationThread的scheduleLaunchActivity方法,scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord,调用sendMessage传递参数

frameworks/base/core/java/android/app/ActivityThread.java:

@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
        CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
        int procState, Bundle state, PersistableBundle persistentState,
        List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
        boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
 updateProcessState(procState, false);
    ActivityClientRecord r = new ActivityClientRecord();
    r.token = token;
    r.ident = ident;
    r.intent = intent;
    r.referrer = referrer;
    r.voiceInteractor = voiceInteractor;
    r.activityInfo = info;
    r.compatInfo = compatInfo;
    r.state = state;
    r.persistentState = persistentState;
    r.pendingResults = pendingResults;
    r.pendingIntents = pendingNewIntents;
    r.startsNotResumed = notResumed;
    r.isForward = isForward;
    r.profilerInfo = profilerInfo;
    r.overrideConfig = overrideConfig;
    updatePendingConfiguration(curConfig);
    sendMessage(H.LAUNCH_ACTIVITY, r);//传递参数
}

sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去,

frameworks/base/core/java/android/app/ActivityThread.java:

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
   ...
      mH.sendMessage(msg);
  }

这里mH指的是H,它是ActivityThread的内部类并继承Handler,H的代码如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

private class H extends Handler {
      public static final int LAUNCH_ACTIVITY         = 100;
      public static final int PAUSE_ACTIVITY          = 101;
...
public void handleMessage(Message msg) {
          if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
          switch (msg.what) {
              case LAUNCH_ACTIVITY: {
                  Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                  final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1
                  r.packageInfo = getPackageInfoNoCheck(
                          r.activityInfo.applicationInfo, r.compatInfo);//2
                  handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3
                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
              } break;
              case RELAUNCH_ACTIVITY: {
                  Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
                  ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                  handleRelaunchActivity(r);
                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
              } break;
            ...
}

查看HhandleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。
在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。
在注释3处调用handleLaunchActivity方法,代码如下所示。

frameworks/base/core/java/android/app/ActivityThread.java

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
      Activity a = performLaunchActivity(r, customIntent);//1
      if (a != null) {
          r.createdConfig = new Configuration(mConfiguration);
          reportSizeConfigurations(r);
          Bundle oldState = r.state;
          handleResumeActivity(r.token, false, r.isForward,
                  !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//2

          if (!r.activity.mFinished && r.startsNotResumed) {      
              performPauseActivityIfNeeded(r, reason);
              if (r.isPreHoneycomb()) {
                  r.state = oldState;
              }
          }
      } else {
          try {
              ActivityManagerNative.getDefault()
                  .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                          Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
          } catch (RemoteException ex) {
              throw ex.rethrowFromSystemServer();
          }
      }
  }

注释1处的performLaunchActivity方法用来启动Activity ,注释2处的代码用来将Activity 的状态置为Resume。如果该Activity为null则会通知ActivityManager停止启动Activity。来查看performLaunchActivity方法做了什么:

frameworks/base/core/java/android/app/ActivityThread.java

  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  ...
        ActivityInfo aInfo = r.activityInfo;//1获取ActivityInfo
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);//2获取APK文件的描述类LoadedApk
        }
        ComponentName component = r.intent.getComponent();//3获取要启动的Activity的ComponentName类
      ...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);//4用类加载器来创建该Activity的实例
           ...
            }
        } catch (Exception e) {
         ...
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);//5创建Application

        ...
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);//6创建要启动Activity的上下文环境
         ...
                }
                /**
                *7用Activity的attach方法初始化Activity
                */
                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);

              ...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8调用Instrumentation的callActivityOnCreate方法来启动Activity
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
        }
        return activity;
}

注释1处用来获取ActivityInfo,在注释2处获取APK文件的描述类LoadedApk。注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。注释4处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释5处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释6处用来创建要启动Activity的上下文环境。注释7处调用Activity的attach方法初始化Activity,attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。注释8处会调用InstrumentationcallActivityOnCreate方法来启动Activity:

frameworks/base/core/java/android/app/Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle,
         PersistableBundle persistentState) {
     prePerformCreate(activity);
     activity.performCreate(icicle, persistentState);//1
     postPerformCreate(activity);
 }

注释1处调用了ActivityperformCreate方法,代码如下所示。

frameworks/base/core/java/android/app/Activity.java

final void performCreate(Bundle icicle) {
      restoreHasCurrentPermissionRequest(icicle);
      onCreate(icicle);
      mActivityTransitionState.readState(icicle);
      performCreateCommon();
  }

performCreate方法中会调用Activity的onCreate方法,这样Activity就启动了,即应用程序就启动了。

荐
                                                        Android  应用启动流程简单整理

本文地址:https://blog.csdn.net/weixin_40303382/article/details/106141344