源码分析Activity的启动过程

2019-05-23  本文已影响0人  空山Echo

当我们启动一个Activity,都将通过startActivityForResult去开始Activity的启动过程。

1. startActivityForResult方法(Activity.java)

在startActivityForResult方法中一个重要方法execStartActivity
execStartActivity方法就像一个魔盒,后续的启动过程跟它的调用者、参数都息息相关

 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            ...
        }
      ...
}

2. execStartActivity方法(Instrumentation.java)

  • 在execStartActivity方法中启动Activity的实现交由ActivityManager.getService()的startActivity方法完成。ActivityManager.getService()得到的就是AMS(ActivityManagerService),是一个Binder。
  • 并且会调用checkStartActivityResult方法检查启动结果
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

3. 由此启动过程转移到AMS的startActivity中

此方法中会调用一系列方法。最终以ActivityStackSupervisor的realStartActivityLocked方法为启动的关键方法,继续启动过程

4. realStartActivityLocked方法(AMS ---->ActivityStackSupervisor.java)

在此方法中调用这样的一段代码app.thread.scheduleLaunchActivity(),并把AMS这边对这个Activity的记录各方面信息当做参数,这样客户端就能获取到Activity的各种信息即ActivityClientRecord。

  • app.thread实际就是ActivityThread的内部类ApplicationThread。也就是调用execStartActivity方法传递的参数mMainThread.getApplicationThread()
  • 由此启动过程从服务又回到客户端了
//ActivityStack类
final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
    //...  
    try {
        //...
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info,
                new Configuration(mService.mConfiguration),
                r.compat, r.icicle, results, newIntents, !andResume,
                mService.isNextTransitionForward(), profileFile, profileFd,
                profileAutoStop);
        //...
    } catch (RemoteException e) {
        //...
    }
    //...    
    return true;
}

5. scheduleLaunchActivity() (ActivityThread.java)

这个方法保存Activity相关信息后,完成一件事:向名为H的Handler发送一条启动消息,接下来Handler H将对“LAUNCH_ACTIVITY”这个消息进行处理,交由handleLaunchActivity方法实现。

//ActivityThread类
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
        Bundle state, List<ResultInfo> pendingResults,
        List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
        String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
    ActivityClientRecord r = new ActivityClientRecord();
    r.token = token;
    r.ident = ident;
    r.intent = intent;
    r.activityInfo = info;
    r.compatInfo = compatInfo;
    r.state = state;
    r.pendingResults = pendingResults;
    r.pendingIntents = pendingNewIntents;
    r.startsNotResumed = notResumed;
    r.isForward = isForward;
    r.profileFile = profileName;
    r.profileFd = profileFd;
    r.autoStopProfiler = autoStopProfiler;
    updatePendingConfiguration(curConfig);
    queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}

6. handleLaunchActivity方法(ActivityThread.java)

由H Handler处理消息也意味着启动过程到了主线程中

  • 此方法中将调用performLaunchActivity方法最终完成Activity对象的创建和启动过程
  public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        ...
        final Activity a = performLaunchActivity(r, customIntent);

        ...
        return a;
    }

7. performLaunchActivity方法(ActivityThread.java)

完成以下几件事

  1. 从ActivityClientRecord中获取待启动Activity组件的信息
  2. 通过Instrumentation的newActivity方法使用类加载器创建Activity对象
  3. 通过LoadedApk的makeApplication方法尝试创建Application对象
  4. 创建ContextImpl对象并通过attach方法来完成一些重要数据的初始化(由attach方法ContextImpl与Activity建立关联)
  5. 调用Activity的onCreate方法

这样就完成了整个启动过程

  1. 新的Activity何时被创建
  2. Activity的onCreate方法何时被系统回调?
    https://www.jianshu.com/p/4edf1987a940
上一篇下一篇

猜你喜欢

热点阅读