Activity启动过程-Android 27API

简录

Activity启动过程

Launcher请求AMS过程[1]
ApplicationThread的调用过程[2]
ActivityThread启动Activity[3]

Launcher请求AMS过程

1.1 我们从桌面的快捷图标启动根Activity,此时会通过Launcher请求AMS启动该应用程序,Launcher会调用startActivitySafly方法函数
 public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        ...
​         //传入一个Flag标识,这样根Activity会在新任务栈中启动
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        try {
            if (Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                     || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((ShortcutInfo) item).isPromise()) {
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                startActivity(intent, optsBundle);
            } else {
                LauncherAppsCompat.getInstance(this).startActivityForProfile(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            return true;
        } catch (ActivityNotFoundException|SecurityException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
        }
        return false;
    }
1.2 调用startActivity方法函数启动Activity,此方法的实现在Activity类中
  @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }
1.3.源码中会调用startActivityForResult方法函数,其中options参数的有无决定着我们当前启动Activity是否需要有返回结果,由于我们启动的根Activity是不要返回值的所以此时调用的是startActivityForResult(intent, -1);
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    //mParent判断当前启动的Activity是否有其父类的存在,由于我们启动的根目录所以此时Activity没有父类,所以此判断结果为Ture​
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        ...
        cancelInputsAndStartExitTransition(options);
    } else {
        ...
    }
}
1.4.可以看出接下来调用的事Instrumentation的实例mInstrumentation的execStartActivity方法函数(注:Instrumentation类的作用是来监控应用程序和系统的交互)
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    ...
    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;
}
1.5.ServiceManager通过调用getService函数方法获取AMS的代理实例,进而调用AMS的startActivity方法函数
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };​
1.6.看至此处我们应该明白了,AMS的最终实现是采用AIDL的方式实现的进而调取startActivity方法

ApplicationThread的调用过程

2.1.进入到AMS的startActivity方法后是如何调入到ApplicationThread的呢?我们继续看源码,看startActivity里面的实现
@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());
}
@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) {
     //官方解释判断​当前进程是否被隔离,若是隔离进程将会抛出一个SecurityException异常,然后退出执行流程
    enforceNotIsolatedCaller("startActivity");
    //检查用户许可,若不被许可则抛出​SecurityException异常,
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}​
2.2.源码在此处无任何实现只是调取了AMS自身的startActivityAsUser方法函数(参数UserHandle.getCallingUserId(),官方解释UserHandle这个类是用来记录用户在设备上的信息而函数getCallingUserId()获取的事用户ID),接着调用了mActivityStarter.startActivityMayWait方法
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) {
​     ...
    synchronized (mService) {
        ...
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        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);
        
         ...
        return res;
    }
}
​
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) {
    if (TextUtils.isEmpty(reason)) {
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    mLastStartReason = reason;
    mLastStartActivityTimeMs = System.currentTimeMillis();
    mLastStartActivityRecord[0] = null;
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask);
    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }
    // Aborted results are treated as successes externally, but we must track them internally.
    return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}​​
2.3.紧接着又调用了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, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
        ...
        //​创建一个ActivityRecord的实例用来描述即将启动的Activity属性信息
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, container, options, sourceRecord); 
        if (outActivity != null) {
            outActivity[0] = r;
        }
        ...
            doPendingActivityLaunchesLocked(false);
            return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }
2.4.startActivity方法函数继续执行多态执行
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;
    try {
        mService.mWindowManager.deferSurfaceLayout();
        result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity);
    } finally {
        // If we are not able to proceed, disassociate the activity from the task. Leaving an
        // activity in an incomplete state can lead to issues, such as performing operations
        // without a window container.
        if (!ActivityManager.isStartResultSuccessful(result)
                && mStartActivity.getTask() != null) {
            mStartActivity.getTask().removeActivity(mStartActivity);
        }
        mService.mWindowManager.continueSurfaceLayout();
    }
    postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId,  mSourceRecord,
            mTargetStack);
    return result;
}
2.5.紧接着调用startActivityUnchecked方法函数
// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    //设置Activity初始状态​
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);
    //计算任务启动标记​
    computeLaunchingTaskFlags();
    //计算源堆栈​
    computeSourceStack();
    //为Intent设置Flag标记​
    mIntent.setFlags(mLaunchFlags);
    //用来描述Activity堆栈信息​
    ActivityRecord reusedActivity = getReusableIntentActivity();
    ...
​​
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                && mStartActivity != topTaskActivity)) {
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            mWindowManager.executeAppTransition();
        } else {
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else {
        mTargetStack.addRecentActivityLocked(mStartActivity);
    }
    ...
    return START_SUCCESS;
}
2.6.ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数方法
boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    if (!readyToResume()) {
        return false;
    }
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    //获取处在栈顶正在运行的ActivityRecord​
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    //若ActivityRecord的实例为Null 或 ActivityRescord实例的状态不是Resume则调用
    //由于我们启动的是根Activity所以if语句结果为Ture​​
    if (r == null || r.state != RESUMED) { 
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }
    return false;
}
2.7.接下来源码调用ActivityStack的实例mFocusedStack的resumeTopActivityUncheckedLocked方法函数
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
        return false;
    }
    boolean result = false;
    try {
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    if (next == null || !next.canTurnScreenOn()) {
        checkReadyForSleep();
    }
    return result;
}
2.恢复栈顶的Activity,继续调用resumeTopActivityInnerLocked方法函数->其函数方法中又通过ActivityStackSupervisor的实例mStackSupervisor调取了startSpecificActivityLocked方法函数
void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
     //获取即将启动的Activity的进程
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
    r.getStack().setLaunchTime(r);
   //判断进程和进程的线程是否为Null​
    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}
2.9.判断是否获取了即将启动的Activity的进程并且其进程中是否包含线程,判断成功后调用realStartActivityLocked方法函数
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ...​ logIfTransactionTooLarge(r.intent, r.icicle); app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), [r.info](http://r.info), mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) { if (app.processName.equals(app.info.packageName)) { if (mService.mHeavyWeightProcess != null && mService.mHeavyWeightProcess != app) { Slog.w(TAG, "Starting new heavy weight process " + app + " when already running " + mService.mHeavyWeightProcess); } mService.mHeavyWeightProcess = app; Message msg = mService.mHandler.obtainMessage( [ActivityManagerService.POST](http://ActivityManagerService.POST)_HEAVY_NOTIFICATION_MSG); msg.obj = r; mService.mHandler.sendMessage(msg); } }​​ ...​ }​​

2.10.这里的app.thread是一个IApplicationThread的实例,IApplicationThread是在ApplicationThread实现的,ApplicationThread继承了IApplicationThread.Stub,由于当前代码运行在AMS所在进程,而ApplicationThread通过实现IApplicationThread,使得AMS可以与应用程序进行Binder通信,即成为了AMS与应用程序通信的纽带桥梁.

ActivityThread启动Activity

3.1.应用程序进程创建后运行代表线程的ActivityThread类的实例,用于管理当前应用程序进程的线程,通过调用ApplicationThread内部类的函数scheduleLaunchActivity()启动根Activity
  @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;
            ...
            updatePendingConfiguration(curConfig);
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }​
3.2.scheduleLaunchActivity()会将启动Activity的参数封装成ActivityClientRecord,通过调用sendMessage()向H类发送Handler消息,发送类型为LAUNCH_ACTIVITY并将ActivityClientRecord传递过去;此处的H类为ActivityThread的内部类并且继承与Handler,他是应用程序主线程的消息管理类
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;  //在此处将 msg 所携带的参数 obj 转化成它的原始类型 ActivityClientRecord
​
                  r.packageInfo = getPackageInfoNoCheck(
                          r.activityInfo.applicationInfo, r.compatInfo); 
​
                  handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                  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;
            ...
}
3.3.源码通过调用 getPackageInfoNoCheck()函数获取当前APK文件的属性并将其封装成LoadedApk赋值予ActivityClientRecord的成员变量packageInfo,由于程序启动Activity时需要将Activity所属的APK加载进来,所以此处的LoadedAPK就是用来存储APK文件属性的;接着往下看我们发现源码调用了handleLaunchActivity()函数
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    WindowManagerGlobal.initialize();
    Activity a = performLaunchActivity(r, customIntent);//启动Activity的主流程
    //此处做一层判断​,
   //​若所启动Activity不存在或者启动失败,则会通知AMS停止启动
    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
​        //将Activity的状态置为Resume 做一下分支流程分析
​        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

​​         //若Acitivity已启动完毕 且 Activity在前台不可见​ 
        if (!r.activity.mFinished && r.startsNotResumed) {
​
​            //将Activity的状态设置成Pause状态 做一下分支流程分析
            performPauseActivityIfNeeded(r, reason);
            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }
    } else {
        try {
            //停止Activity启动
            ActivityManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}
3.3.1 将Activity的状态置成 Resume状态

3.3.1.1 源码中调用的handleResumeActivity()是用来将Activity的状态置成 Resume状态

final void handleResumeActivity(IBinder token,
        boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
...
// TODO Push resumeArgs into the activity for consideration
r = performResumeActivity(token, clearHide, reason);​
...​​
}​

3.31.2 此处调用了performResumeActivity()来设置将Activity的状态设置成Resume,再来往下看此方法中的处理

public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    ...
            r.activity.performResume();
    ...​
}​

3.3.1.3 我们发现源码通过唯一标识token从成员变量mActivites中获取当前Activity的属性信息生成ActivityClientRecord实例r,然后调用r的成员变量activity的函数performResume()进行下一步操作

final void performResume() {
    //onRestart()生命周期​
    performRestart();  //1
    //挂起fragment的操作​
    mFragments.execPendingActions(); 
    mLastNonConfigurationInstances = null;
    mCalled = false; 
    // mResumed is set by the instrumentation
    mInstrumentation.callActivityOnResume(this); //将Activity置成onResume状态分支主流程
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onResume()");
    }
    // invisible activities must be finished before onResume() completes
    if (!mVisibleFromClient && !mFinished) {
        Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
        if (getApplicationInfo().targetSdkVersion
                > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
            throw new IllegalStateException(
                    "Activity " + mComponent.toShortString() +
                    " did not call finish() prior to onResume() completing");
        }
    }
    // Now really resume, and install the current status bar and menu.
    mCalled = false;
    mFragments.dispatchResume(); //2
    mFragments.execPendingActions(); 
    onPostResume(); //3
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onPostResume()");
    }
}

3.3.1.4 这段代码中需要讲解的知识点颇多我们进行一 一讲解

  • 序号<1> 调用performRestart()是将Activity的状态设置成Restrat状态,但是我们启动Activity流程onRestart是在onStop之后的,那么我们继续分析源码
final void performRestart() {
...​
if (mStopped) {
mStopped = false;​
...​
 mCalled = false;
mInstrumentation.callActivityOnRestart(this);
if (!mCalled) {
        throw new SuperNotCalledException(
          "Activity " + mComponent.toShortString() +
            " did not call through to super.onRestart()");
         }
          performStart();​
 }​ }
  • 序号<2> 是真对Activity中嵌入的Frament的一个操作,当Activity置成Resume状态后同样的也需要将其中的Frgament置成相对应得状态,并挂起Fragment中正在进行的操作
  • 序号<3> 调用调用onPostResume()目的是 将当前window设置成活动状态,并将ActionBar设置成显示状态

3.3.1.5 我们继续按照将Activity设置成Resume状态分支主流进行分析,可以看到源码通过Instrumentation的实例对象mInstrumentation调用了callActivityOnResume(this)函数,看一下这里面的实现

public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    activity.onResume();
    
    ...
}

3.3.1.6 到此我们终于明白了,Activity的生命周期onResume()的调用最终是由Instrumentation调入到Activity相对应的方法中去的

protected void onResume() {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
    getApplication().dispatchActivityResumed(this);
    mActivityTransitionState.onResume(this, isTopOfTask());
    mCalled = true;
}​
3.3.2 将Activity的状态设置成 Pause状态

3.3.2.1 源码中调用的performPauseActivityIfNeeded(ActivityClientRecord r, String reason)是用来将Activity的状态置成 Pause状态

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }
    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
        EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
                r.activity.getComponentName().getClassName(), reason);
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                    + " did not call through to super.onPause()");
        }
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException("Unable to pause activity "
                    + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
        }
    }
    r.paused = true;
}

3.3.2.2 观察源码可以发现这里依然是通过Instrumentation的实例对象mInstrumentation调用callActivityOnPause(r.activity)函数执行了Activity类中的performPause()->onPause() 函数,最终将Activity设置成Pause状态

public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

3.3.2.3 同过以上的案例讲解我们清楚的了解到,关于Activity的生命周期状态的设置最终都是由Instrumentation相关函数调入到Activity中对应的方法实现的状态的设置

3.3.3 总结

同过以上的案例讲解我们清楚的了解到,关于Activity的生命周期状态的设置最终都是由Instrumentation相关函数调入到Activity中对应的方法实现的状态的设置

3.4.沿着Activity住流程我们继续讲,看一下 performLaunchActivity(r, customIntent)函数的具体实现
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 获取Activity的属性信息,并封装到ActivityInfo中
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
​         //获取APK文件描述信息封装成LoadApk类型赋予给ActivityClientRecord的实例中的packageInfo成员变量中
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    ComponentName component = r.intent.getComponent();
    ...
    //创建要启动的Activity相对应的ContextImpl实例,即Activity的上下文环境,Activity初始化中的相关操作都是交由ContextImpl去实现的​
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        //通过类加载器创建出Activity创建的实例​
        java.lang.ClassLoader cl = appContext.getClassLoader();
        //​最终交由Instrumentation的实例mInstrumentation通过调用newActivity函数​通过类加载器new 出一个Activity实例
        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) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }
    try {
        //根据获取的APK文件的描述信息创建Application实例​,在此方法通过ActivityThread的实例mActivityThread调用Instrumentation的实例mInstrumentation进而调取newApplication方法函数->通过反射创建Application的实例
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        if (activity != null) {
            ...
            //初始化Actvity​
            appContext.setOuterContext(activity);
            //对Activity进行初始化并使Activity与Window关联起来​
            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);
            //设置Activity的主题
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }
            //调用Activity的onCreate生命周期​启动Activity
            activity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            //调用Activity的onSatrt生命周期
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
           ...
        }
        r.paused = true;
        mActivities.put(r.token, r);
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
      ...
    }
    return activity;
}
3.5.在调用到Activity的onCreate生命周期方法后,我们的Activity也就完成它自己的启动过程,至此就完成了启动根Activity的过程

This ALL! Thanks EveryBody!


  1. Launcher请求AMS过程

  2. ApplicationThread的调用过程

  3. ActivityThread启动Activity

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343