Android8.0源码解析——Activity的启动过程

前言

Activity是Android的四大组件,关于Activity 的启动过程是怎么样的昵,下面我们主要通过Android8.0的源码来分析一下。

1、Activity的生命周期:

Activity的生命周期我们都知道有
protected void onCreate(); 
protected void onRestart(); 
protected void onStart(); 
protected void onResume(); 
protected void onPause(); 
protected void onStop(); 
protected void onDestory(); 

2、Activity的启动模式

activity启动时可以设置不同的启动模式,主要是:standrand,singleTop,singleTask,instance等四种启动模式,不同的启动模式在启动Activity时会执行不同的逻辑,系统会按不同的启动模式将Activity存放到不同的activity栈中。 
关于Activity启动模式的详细介绍,可以参考: 

3、Activity的启动进程

通常情况下,一个应用只有一个进程,这个进程就是应用的包名,如果在AndroidManifest.xml中定义Activity时没有指定android:process属性,那么该activity所在的进程就是应用默认的进程(进程名称为包名的进程),我们在AndroidManifest.xml文件中设定activity 的android:process属性来指定activity的启动进程,当activity 启动时首先会检测当前Activity的所属进程启动没,如果没有启动,则先启动该Activity的所属进程,进程启动之后再执行Activity的启动。

4、Intent 启动 Activity

Intent启动Activity的方式有两种,分为显式启动和隐式启动,我们最常用的startactivity就是显式启动,显式启动就是在初始化Intent的时候直接调用需要启动Activity的字节码,显示启动的好处就是:告诉Intent对象将要启动的Activity对象,不需要执行intent filter搜索需要启动哪个Activity,但是显示启动不能启动其他应用的Activity(由于无法获取其他应用Activity的字节码),启动其他应用的Activity需要用隐式启动。

5、Activity启动源码分析

1、从Activity到ActivityManagerService。

我们启动Activity启动时,首先从Activity源码会请求调用ActivityManagerService中的方法,大致流程如下图所示:

一、 首先我们在Activity中调用startActivity(intent)时会执行下面的方法。
@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}
上面的方法会调用下面的方法。由于传入的options参数是null 所以会执行startActivityForResult(intent ,-1);
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}
由于在上一步中我们传入的options是null所以我们执行startActivityForResult(intent,-1);
在这里我们会发现startActivity最终调用的还是startActivityForResult方法,细心的读者会想“ startActivity最终调用的还是startActivityForResult方法,那么为什么我们在Activity调用startActivity不可以在Activity中会调用onActivityResult,而调用startActivityForResult时可以回调onActivityResult? "
我们继续往下看代码,看完这个 startActivityForResult 的源码就知道了
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
上面的方法又会调用下面的 startActivityForResult 方法
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);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}
看了上面的源码我们才发现, 由于第一次启动Activity所以mParent值为空,所以会执行if分支,原来在第13行会判断returnCode是否大于0,如果大于0, mStartedActivity 置为true, 只有当它为true时才会在Activity中回调onActivityResult 。通过前面的代码我们发现,由于我们之前在Activity中调用 startActivity 后最终调用 startActivityForResult 时传入的 returnCode 为-1,所以才不会回调 onActivityResult

上面我们看由于mParent为空,所以执行 mInstrumentation.execStartActivity方法,这里的 mInstrumentation Instrumentation 的一个对象, Instrumentation 是Android系统中启动Activity的一个实际操作类,即:Activity 在Application的进程端的启动实际都是由Instrumentation执行的。由于Activity的启动分为Application进程端的启动和SystemService端的启动,所以这里才说是Application进程端的启动是由Instrumentation执行的,下面我们来看下它的 execStartActivity 方法的源码:
 /**
 * <p>This method throws {@link android.content.ActivityNotFoundException}
 * if there was no Activity found to run the given Intent.
 *
 * @param who The Context from which the activity is being started.(Activity对象)
 * @param contextThread The main thread of the Context from which the activity
 *                      is being started.(Binder对象,是主进程的context对象)
 * @param token Internal token identifying to the system who is starting 
 *              the activity; may be null.(也是一个Binder对象,指向了服务端一个ActivityRecord对象)
 * @param target Which activity is performing the start (and thus receiving 
 *               any result); may be null if this call is not being made
 *               from an activity.(为启动的Activity)
 * @param intent The actual Intent to start.(启动的Intent对象)
 * @param requestCode Identifier for this request's result; less than zero 
 *                    if the caller is not expecting a result.(请求码)
 * @param options Addition options.(参数)
 *
 * @return To force the return of a particular result, return an 
 *         ActivityResult object containing the desired data; otherwise
 *         return null.  The default implementation always returns null.
 *
 * @throws android.content.ActivityNotFoundException
 *
 * @see Activity#startActivity(Intent)
 * @see Activity#startActivityForResult(Intent, int)
 * @see Activity#startActivityFromChild
 *
 * {@hide}
 */
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
   ......
    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;
}
在这个方法中我们发现主要调用了 ActivityManager.getService().startActivity() 方法,那么ActivityManager.getService()又是啥昵?我们来看下 源码:
public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}
what???返回的是IActivityManagerSingleton.get();那IActivityManagerSingleton又是个什么鬼东东?我们继续往下看源码:
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;
            }
        };
我们发现它返回的是 IActivityManager.Stub.asInterface (b);我们都知道 Stub 是AIDL(Android Interface Definition Language)生成的 一个Binder类 ,当客户端和服务端要跨进程走transact过程时,它的逻辑就时有Stub的内部类Proxy来代理的。而 asInterdace ()方法的作用是: 将服务端的Binder对象转换为客户端所需要的AIDL接口类型。如果客户端和服务端在同一个进程他返回的就是服务端Stub对象本身,否则他返回的就是系统封装后的Stub.proxy对象。
下面我们来看下 IActivityManager.Stub.asInterface 到底是啥?其实我们发现 ActivityManagerService继承自IActivityManager.Stub ,所以上面返回的就是一个ActivityManagerService对象。
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
}

2、从ActivityManagerService 到ApplicationThread

所以 ActivityManager.getService().startActivity() 执行的是ActivityManagerService中的 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());
}
这里有调用了 startActivityAsUser 方法,我们继续往下看它的源码:
@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) {
    enforceNotIsolatedCaller("startActivity");
    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, null,
            "startActivityAsUser");
}
这里返回了mActivtyStarter.startActivityMayWait方法,mActivityStarter是ActivityStarter的对象,ActivityStarter是Android 7.0新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联。我们来看它的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,
            IActivityContainer iContainer, TaskRecord inTask, String reason) {
             .........code............
        synchronized (mService) {
             ......code...............
         
            //启动Activity
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask, reason);

            Binder.restoreCallingIdentity(origId);
            //如果配置Configration发生变化,则调用AMS的updateConfigurationLocked进行处理
            if (stack.mConfigWillChange) {
                // If the caller also wants to switch to a new configuration,
                // do so now.  This allows a clean switch, as we are waiting
                // for the current activity to pause (so we will not destroy
                // it), and have not yet started the next activity.
                //如果调用方也希望切换到新配置
                //现在就这样做。这允许一个干净的开关,因为我们正在等待
                //为当前活动暂停(因此我们不会破坏)
                //它还没有启动下一个活动。
                mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                        "updateConfiguration()");
                stack.mConfigWillChange = false;
                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                        "Updating to new configuration after starting activity.");
                mService.updateConfigurationLocked(globalConfig, null, false);
            }
            ..........code..........
            mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }
startActivityMayWait这个方法的源码比较多,我们省略掉一些非重要的源码,这里重点我们看调用的 startActivityLocked方法。
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, ActivityStackSupervisor.ActivityContainer container,
        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,
            container, inTask);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }
    return mLastStartActivityResult;
}
我们看到这个方法,首先判断Activity启动的理由是否为空,如果为空抛出异常,紧接着调用了它的内部方法 startActivity ,那么我们下面来继续看 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) {
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
            = options != null ? options.popAppVerificationBundle() : null;

    ProcessRecord callerApp = null;
    if (caller != null) {
        //获取launcher进程
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            //获取launcher进程的pid 和Uid并赋值
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller
                    + " (pid=" + callingPid + ") when starting: "
                    + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
   ..............code.................
   //创建将要启动的Activity的描述类ActivityRecord
    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;
    }
   ..........code...............  
    doPendingActivityLaunchesLocked(false);
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
            options, inTask, outActivity);
}
这个方法中的逻辑还是比较多的,这里还是列出我们重点关心的代码,我们看到首先在这个方法中会根据IApplicationThread类型的一个对象来获取launcher进程。随后我们又看到根据获取的进程callerApp创建一个 ActivityRecord 对象,这个类是类似与 ProcessRecord ,就是用来描述Activity,记录一个Activity对象的所有信息。所以这里创建的r就是记录将要启动的Activity的所有信息。紧接着将它传给一个ActivityRecord[]类型的的outActivity,而这个outActivity和之前创建的对象我们看到它是做为入参继续传入下一个start Activity方法。
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;
}
紧接着这个方法又调用了 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) {
        ......code......
        // Should this be considered a new task?
        int result = START_SUCCESS;
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {//
            newTask = true;
        //创建新的TaskRecord
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
        if (result != START_SUCCESS) {
            return result;
        }
        ......code......
        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);
        }
        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
                preferredLaunchDisplayId, mTargetStack.mStackId);

        return START_SUCCESS;
    }
从第一行注释理解,这个方法主要处理栈管理相关的一些逻辑,启动根Activity时会将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK,所以会执行if条件里面的,在第12行我们看到会通过setTaskFromReuseOrCreateNewTask方法创建一个TaskRecord对象,TaskRecord类似于ActivityRecordd,这个类的作用是描述一个Activity任务栈,也就是说 setTaskFromReuseOrCreateNewTask方法会创建一个新的Activity任务栈。主要代码是我们看到在41行,调用的ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
   boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        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;
    }
这个方法我们主要看第6行及后面的判断语句,第6行这个方法是获取启动Activity所在栈的栈顶处于非停止状态的ActivityRecord。紧接着后面判断获取的这个ActivityRecord对象为空 或者它的状态不是RESUME,就会执行if里面的语句,调用ActivityStack的 resumeTopActivityUncheckedLocked方法,对于将要启动的Activity肯定满足条件,所以下面我们来看ActivityStack的 resumeTopActivityUncheckedLocked方法,
  boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        // When resuming the top activity, it may be necessary to pause the top activity (for
        // example, returning to the lock screen. We suppress the normal pause logic in
        // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end.
        // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure
        // any necessary pause logic occurs.
        mStackSupervisor.checkReadyForSleepLocked();

        return result;
    }
这里又调用了resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
      ......code......
           mStackSupervisor.startSpecificActivityLocked(next, true, true);
       }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
       return true;
}
这个方法中只需要关注调用的ActivityStackSupervisor 的startSpecificActivityLocked方法,代码如下所示:
  void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?获取将要启动Activity所在应用程序的进程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);

        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);
    }
这个方法首先获取将要启动Activity所在应用程序的进程,之后判断该进程不为空的话,且其对象thread不为空,就会调用15行的 realStartActivityLocked方法,并且将该进程作为入参传入方法:
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, new Configuration(mService.mConfiguration),
                  new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                  task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                  newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
  ...      
      return true;
  }
上面提到app.thread指的是IApplicationThread,它的是现实ActivityThread的内部类,ApplicationThread,其中ApplicationThread继承了IApplicationThread.Stub。所以这里调用了ApplicationThread的 scheduleLuaunchActivity。说到这里就是AMS与ApplicationThread之间通过Binder通信。

总结

关于Activity的启动流程,先看到ApplicationThread这里,后面的流程后续补上,对于前面的流程相信大家看得也是云里雾里的,我们通过下面的流程图来简单总结一下:


猜你喜欢

转载自blog.csdn.net/u013132758/article/details/79919789