美文网首页
Activity启动流程

Activity启动流程

作者: 要学的东西太多了 | 来源:发表于2020-06-12 10:58 被阅读0次

Activity的启动流程从startActivity开始,桌面点击应用其实也是调用的startActivity方法。分析可以划分为三部分:

  • ActivityThread -> ActivityManagerService(AMS);
  • AMS -> ApplicationThread;
  • ApplicationThread -> ActivityThread;

首先分析ActivityThread -> ActivityManagerService(AMS)。

  • startActivity方法里面,调用了startActivityForResult方法:
public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }

这里的requestCode为-1,表示不需要知道activity的启动结果。

  • startActivityForResult里面也比较简单,直接调用了Instrumentation的execStartActivity方法:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
       //...
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
        //...
    }

Activity和Instrumentation的关系比较密切,后面会分析到,Activity的生命周期方法都是通过它调用的。mMainThread.getApplicationThread(),这里的mMainThread就是我们的ActivityThread,getApplicationThread获取的是一个ApplicationThread对象,ApplicationThread是Activitythread的内部类,继承自IApplicationThread.Stub,了解AIDL的都知道它是个IBinder对象,可以用于进程间通信的接口调用。

  • Instrumentation的execStartActivity主要调用了AMS的startActivity方法,这时候处理逻辑就从ActivityThread转到AMS中了:
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        //...
            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);
       //...
        return null;
    }

接下来分析AMS到ApplicationThread的处理流程

  • AMS的处理逻辑较为复杂,主要包括以下几部分:
1. 处理启动activity的flag、处理intent、生成activityRecord对象;
2. 判断是否需要创建新的TaskRecord对象,是否需要创建新的ProcessRecord对象;
3. 在ActivityStarter、ActivityStackSupVisor、ActivityStack几个类里面做逻辑处理。

这里面很多类,我们需要先理解他们的作用。ActivityStarter顾名思义就是Activity的启动者,ActivityStackSupVisor是ActivityStack的管理者。ActivityStack是TaskRecord的管理类,内部维护了ArrayList<TaskRecord>集合。TaskRecord就是Activity任务栈,每个TaskRecord里面维护了一个ArrayList<ActivityRecord>集合。

  • AMS的startActivity方法直接调用了startActivityAsUser方法:
@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
  • AMS的startActivityAsUser方法调用了ActivityStarter的startActivityMayWait:
@Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
       //...
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
    }
  • ActivityStarter的startActivityMayWait调用了startActivityLocked方法:
final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
        //...
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
          //...
        }
    }
  • ActivityStarter的startActivityLocked方法又调用了另一个startActivity方法:
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
        //...
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);

        //...
        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
    }
  • ActivityStarter的这个方法里面创建了activityRecord对象,然后接着调用另一个startActivity方法:
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
       //...
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);
      //...
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }
  • 这个startActivity方法又调用了startActivityUnchecked方法:
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        int result = START_CANCELED;
          //...
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
         //...
        return result;
    }
  • ActivityStarter的startActivityUnchecked方法处理了几件事,计算启动flag、给intent设置flag,根据标识判断是否创建新的任务栈,然后调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked:
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        //...
        computeLaunchingTaskFlags();

        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

         //...
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        }  //...
         //...
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
        //...
        return START_SUCCESS;
    }
  • ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法调用了ActivityStack的resumeTopActivityUncheckedLocked方法:
boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

       //...
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        //...
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        //...
        return false;
    }
  • ActivityStack的resumeTopActivityUncheckedLocked接着调用了resumeTopActivityInnerLocked方法:
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
          //...
          if (mResumedActivity != null) {
            pausing |= startPausingLocked(userLeaving, false, next, false);
          }
          //...
          mStackSupervisor.startSpecificActivityLocked(next, true, true);
          //...
          return true;
    }

这里是先将栈顶activity pasued,然后才启动新的activity,所以在activity的onpause方法里面不能做太多事情,否则影响新的activity启动。

  • startPausingLocked会调用ApplicationThread的schedulePauseActivity方法,这里和scheduleLunchActivity的流程相似,后面会介绍到。
  • startSpecificActivityLocked方法又回到了ActivityStackSupervisor里面,这里调用realStartActivityLocked,还会判断进程是否创建,没有会新建:
void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
            //...
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            //...
      //这里会新建进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
  • realStartActivityLocked主要是调用ApplicationThread的scheduleLaunchActivity,这里就由AMS转到ApplicationThread里面了:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);
             return true;
    }

最后,分析下ApplicationThread -> Activity的流程

  • scheduleLaunchActivity做的事情很简单,构建ActivityClientRecord对象,然后调用sendMessage方法:
@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方法就是通过mH发送消息,mH是ActivityThread的内部类,就将线程切换到ActivityThread了:
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
  • mH对LAUNCH_ACTIVITY消息的处理,调用了handleLaunchActivity方法,handleLaunchActivity先调用了performLaunchActivity来获取activity,然后调用handleResumeActivity方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
       //...
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
           //...
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
             //...
          }
            //...
    }
  • performLaunchActivity里面做了下面几件事:
    1.初始化ContextImpl;
    2.创建activity对象;
    3.如果有必要初始化application;
    4.调用attach方法关联;
    5.调用mInstrumentation的callActivityOnCreate方法:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        //...
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
             //...
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            //...
                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);

                 //...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                 //...
            mActivities.put(r.token, r);

         //...
        }
        return activity;
    }
  • attach方法里面主要初始化了PhoneWindow对象,并设置activity的application对象、主线程等信息,还把WindowManager设置给window。
  • callActivityOnCreate方法调用activity的performCreate方法:
public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
  • performCreate方法回调了onCreate生命周期方法,并分发给fragment的onCreate。
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        mCanEnterPictureInPicture = true;
        restoreHasCurrentPermissionRequest(icicle);
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        mActivityTransitionState.readState(icicle);
        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                com.android.internal.R.styleable.Window_windowNoDisplay, false);
        mFragments.dispatchActivityCreated();
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    }

到这里我们activity已经启动起来了,但还不是可见的,原因是windowmanager还没有真正添加view。

  • 在oncreate方法里面,我们会调用setcontentview方法,会将view的信息添加到phonewindow中。
  • 那么什么时候才真正可见呢?在上面handleLaunchActivity方法中,最后调用了handleResumeActivity方法,这里除了回调生命周期方法外,还调用了activity的wm的addView方法,这里才真正可见:
final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        //...
        r = performResumeActivity(token, clearHide, reason);

         //...
                if (a.mVisibleFromClient) {
                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
                        wm.addView(decor, l);
                    }
                    //...
                }
         //...
    }

相关文章

网友评论

      本文标题:Activity启动流程

      本文链接:https://www.haomeiwen.com/subject/jllgtktx.html