Activity是Android应用与用户交互的界面,了解Activity的启动流程可以加深我们对Activity理解。sdk版本25
一、发起启动Activity的请求
通常我们会通过startActivity()
来打开一个新的Activity。
startActivity(new Intent(this, SecondActivity.class));
1、Activity & startActivityForResult()
该方法最终会调用Activity的 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) {mStartedActivity = true;}cancelInputsAndStartExitTransition(options);} 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 为null,执行Instrumentation类的execStartActivity()
方法,该参数中mMainThread.getApplicationThread()
返回的是一个ApplicationThread对象,而ApplicationThread又是IBinder
的一个子类,负责后面ActivityThread和AMS之间的通信。
2、Instrumentation & execStartActivity
方法
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 = ActivityManagerNative.getDefault().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;}
在execStartActivity方法中会执行ActivityManagerNative.getDefault().startActivity
方法。来看一下ActivityManagerNative.getDefault()方法返回值。
3、ActivityManagerNative & getDefault()
static public IActivityManager getDefault() {return gDefault.get();}private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {protected IActivityManager create() {IBinder b = ServiceManager.getService("activity");if (false) {Log.v("ActivityManager", "default service binder = " + b);}IActivityManager am = asInterface(b);if (false) {Log.v("ActivityManager", "default service = " + am);}return am;}};
gDefault 是一个单例方法,该方法返回一个IActivityManager 对象。而ServiceManager.getService("activity");
则获得一个ActivityManagerService 服务。并将这个ActivityManagerService 通过asInterface(b)
方法返回。
asInterface(b)
方法如下:
static public IActivityManager asInterface(IBinder obj) {if (obj == null) {return null;}IActivityManager in =(IActivityManager)obj.queryLocalInterface(descriptor);if (in != null) {return in;}return new ActivityManagerProxy(obj);}
可以看到asInterface返回的是一个ActivityManagerProxy代理类。即ActivityManagerNative.getDefault()
返回的是ActivityManagerProxy对象,所以我们看一下ActivityManagerProxy的startActivity方法
4、ActivityManagerProxy & startActivity
class ActivityManagerProxy implements IActivityManager
{public ActivityManagerProxy(IBinder remote){mRemote = remote;}public IBinder asBinder(){return mRemote;}public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(caller != null ? caller.asBinder() : null);data.writeString(callingPackage);intent.writeToParcel(data, 0);data.writeString(resolvedType);data.writeStrongBinder(resultTo);data.writeString(resultWho);data.writeInt(requestCode);data.writeInt(startFlags);if (profilerInfo != null) {data.writeInt(1);profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);} else {data.writeInt(0);}if (options != null) {data.writeInt(1);options.writeToParcel(data, 0);} else {data.writeInt(0);}mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);reply.readException();int result = reply.readInt();reply.recycle();data.recycle();return result;}...
}
先看一下ActivityManagerProxy 的继承关系
-> IInterface
- -> IActivityManager
- - -> ActivityManagerProxy
所以ActivityManagerProxy 是一个典型的Binder机制,目的为了将消息从ActivityManagerNative发送到SystemService进程中,此处SystemService是ActivityManagerService。
在ActivityManagerProxy 中,通过Binder机制将消息发送到ActivityManagerService中,下面看一下ActivityManagerService的startActivity方法
二、ActivityManagerService 接收启动请求
1、下面来看ActivityManagerService 的startActivity()
方法
@Overridepublic 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());}
在startActivity()会调用startActivityAsUser()方法,而在startActivityAsUser方法中又会调用ActivityStarter 的 startActivityMayWait()
方法
2、ActivityStarter & 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, IActivityManager.WaitResult outResult, Configuration config,Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask) {...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);...return res;
}
上面方法又会继续调用startActivityLocked
方法。
3、ActivityStarter & startActivityLocked()
final 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) {int err = ActivityManager.START_SUCCESS;...ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,requestCode, componentSpecified, voiceSession != null, mSupervisor, container,options, sourceRecord);...try {mService.mWindowManager.deferSurfaceLayout();err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true, options, inTask);} finally {mService.mWindowManager.continueSurfaceLayout();}return err;}
在此方法中创建了ActivityRecord
对象,并调用了startActivityUnchecked方法。
3、ActivityStarter & startActivityUnchecked()
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {...mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);...return START_SUCCESS;
}
这个方法里面会判断Activity的启动模式,并判断是否需要回调onNewIntent()方法。
最终会执行mSupervisor.resumeFocusedStackTopActivityLocked()
方法。
而resumeFocusedStackTopActivityLocked中会执行ActivityStack的resumeTopActivityUncheckedLocked
方法。在resumeTopActivityUncheckedLocked中,会执行resumeTopActivityInnerLocked
方法。用来将Activity显示在栈顶
4、ActivityStack & resumeTopActivityInnerLocked
resumeTopActivityInnerLocked方法做的事情太多了。这里分开来讲。
①、执行栈顶Activity的onPause方法。
// We need to start pausing the current activity so the top one can be resumed...final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);if (mResumedActivity != null) {if (DEBUG_STATES) Slog.d(TAG_STATES,"resumeTopActivityLocked: Pausing " + mResumedActivity);pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);}
ActivityStack & startPausingLocked()
ActivityRecord mResumedActivity = null;final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, boolean dontWait) {ActivityRecord prev = mResumedActivity;...if (prev.app != null && prev.app.thread != null) {try {...prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);} catch (Exception e) {...}} else {...}}
这里会调用prev.app.thread
的schedulePauseActivity方法。thread其实就是ActivityThread的内部类ApplicationThread。
ApplicationThread & schedulePauseActivity
public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {int seq = getLifecycleSeq();if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this+ " operation received seq: " + seq);sendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,token,(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),configChanges,seq);}
上面方面通过handler机制在接收消息的地方会执行handlePauseActivity()方法。
private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) {ActivityClientRecord r = mActivities.get(token);if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {return;}if (r != null) {//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);if (userLeaving) {performUserLeavingActivity(r);}r.activity.mConfigChangeFlags |= configChanges;performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");// Make sure any pending writes are now committed.if (r.isPreHoneycomb()) {QueuedWork.waitToFinish();}// Tell the activity manager we have paused.if (!dontReport) {try {ActivityManagerNative.getDefault().activityPaused(token);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}mSomeActivitiesChanged = true;}}
在handlePauseActivity方法中后面会执行一系列方法:
handlePauseActivity -> performPauseActivity -> performPauseActivityIfNeeded
-> Instrumentation.callActivityOnPause -> activity.performPause() -> activity.onPause()
经过一些列的方法调用,最终会执行activity的onPause()方法。
上面还有一句ActivityManagerNative.getDefault().activityPaused(token);
。这段代码会执行ActivityManagerService中的activityPaused。最终又会执行到我们的resumeTopActivityInnerLocked中,该方法最后会执行mStackSupervisor.startSpecificActivityLocked方法
②、ActivityStackSupervisor & startSpecificActivityLocked
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);r.task.stack.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所在进程是否已经启动,若是启动的话则执行realStartActivityLocked
方法,真正启动Activity的地方。若是没有启动则先执行mService.startProcessLocked
启动Activity进程,在启动Activity
三、启动Activity所在进程
1、ActivityManagerService & startProcessLocked
private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {...if (entryPoint == null) entryPoint = "android.app.ActivityThread";Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +app.processName);checkTime(startTime, "startProcess: asking zygote to start proc");Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,app.info.dataDir, entryPointArgs);...}
在startProcessLocked中会调用Process.start()方法启动进程,并且传入了processClass需要启动进程的类名"android.app.ActivityThread"
。
2、启动进程 Process.start
/*** Start a new process.* * <p>If processes are enabled, a new process is created and the* static main() function of a <var>processClass</var> is executed there.* The process will continue running after this function returns.* @param processClass The class to use as the process's main entry* point.* @param niceName A more readable name to use for the process.* @param uid The user-id under which the process will run.* @param gid The group-id under which the process will run.* @param gids Additional group-ids associated with the process.* @param debugFlags Additional flags.* @param targetSdkVersion The target SDK version for the app.* @param seInfo null-ok SELinux information for the new process.* @param abi non-null the ABI this app should be started with.* @param instructionSet null-ok the instruction set to use.* @param appDataDir null-ok the data directory of the app.* @param zygoteArgs Additional arguments to supply to the zygote process.* * @return An object that describes the result of the attempt to start the process.* @throws RuntimeException on fatal start failure* * {@hide}*/public static final ProcessStartResult start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String[] zygoteArgs) {try {return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, zygoteArgs);} catch (ZygoteStartFailedEx ex) {Log.e(LOG_TAG,"Starting VM process through Zygote failed");throw new RuntimeException("Starting VM process through Zygote failed", ex);}}
从该方法的注释也可以看到该方法的作用就是启动一个新的进程。并且参数processClass作为进程的入口类,并启动该类中的main()方法。而该类就是android.app.ActivityThread
。然后执行startViaZygote方法,通过
zygote 加载进程。
3、Process & startViaZygote
/*** Starts a new process via the zygote mechanism.*/private static ProcessStartResult startViaZygote(final String processClass,final String niceName,final int uid, final int gid,final int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String[] extraArgs)throws ZygoteStartFailedEx {synchronized(Process.class) {...return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);}}
该方法的注释是:通过zygote
机制来加载执行新的进程。
继续查看zygoteSendArgsAndGetResult()方法
3、Process & zygoteSendArgsAndGetResult
/*** Sends an argument list to the zygote process, which starts a new child* and returns the child's pid. Please note: the present implementation* replaces newlines in the argument list with spaces.** @throws ZygoteStartFailedEx if process start failed for any reason*/private static ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args)throws ZygoteStartFailedEx {try {// Throw early if any of the arguments are malformed. This means we can// avoid writing a partial response to the zygote.int sz = args.size();for (int i = 0; i < sz; i++) {if (args.get(i).indexOf('\n') >= 0) {throw new ZygoteStartFailedEx("embedded newlines not allowed");}}/*** See com.android.internal.os.ZygoteInit.readArgumentList()* Presently the wire format to the zygote process is:* a) a count of arguments (argc, in essence)* b) a number of newline-separated argument strings equal to count** After the zygote process reads these it will write the pid of* the child or -1 on failure, followed by boolean to* indicate whether a wrapper process was used.*/final BufferedWriter writer = zygoteState.writer;final DataInputStream inputStream = zygoteState.inputStream;writer.write(Integer.toString(args.size()));writer.newLine();for (int i = 0; i < sz; i++) {String arg = args.get(i);writer.write(arg);writer.newLine();}writer.flush();// Should there be a timeout on this?ProcessStartResult result = new ProcessStartResult();// Always read the entire result from the input stream to avoid leaving// bytes in the stream for future process starts to accidentally stumble// upon.result.pid = inputStream.readInt();result.usingWrapper = inputStream.readBoolean();if (result.pid < 0) {throw new ZygoteStartFailedEx("fork() failed");}return result;} catch (IOException ex) {zygoteState.close();throw new ZygoteStartFailedEx(ex);}}
在该方法中会通过socket通信的方式让Zygote进程fork出了一个新的进程。并且根据反射加载我们之前传入类名android.app.ActivityThread
,并执行ActivityThread的main()方法。
四、执行ActivityThread的main()方法
public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");SamplingProfilerIntegration.start();// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0("<pre-initialized>");Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}
在main()方法中对Looper进行绑定,创建了一个UI线程的消息队列,创建了ActivityThread对象,并且执行了ActivityThread的attach()方法。下面来看一下attach()方法做了些什么
private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {...final IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}// Watch for getting close to heap limit.//添加一个垃圾回收观察者,每当系统触发垃圾回收的时候就会在run方法里面去//计算应用使用了多少内存,如果超过总量的四分之三就会尝试释放内存BinderInternal.addGcWatcher(new Runnable() {@Override public void run() {if (!mSomeActivitiesChanged) {return;}Runtime runtime = Runtime.getRuntime();long dalvikMax = runtime.maxMemory();long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();if (dalvikUsed > ((3*dalvikMax)/4)) {if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)+ " total=" + (runtime.totalMemory()/1024)+ " used=" + (dalvikUsed/1024));mSomeActivitiesChanged = false;try {mgr.releaseSomeActivities(mAppThread);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}}});...} }
我们知道Binder机制是C/S模式,ActivityManagerNative和ActivityManagerService就是一个Binder机制,ActivityManagerNative相当于客户端,所以上面mgr.attachApplication(mAppThread);
最终会执行ActivityManagerService的attachApplication方法
1、ActivityManagerService & attachApplication()
@Overridepublic final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}}
该方法会继续执行attachApplicationLocked方法
2、ActivityManagerService & attachApplicationLocked()
...// See if the top visible activity is waiting to run in this process...if (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}...
继续执行ActivityStackSupervisor.attachApplicationLocked
方法
3、ActivityStackSupervisor & attachApplicationLocked
...if (realStartActivityLocked(hr, app, true, true)) {didSomething = true;}...
这里会执行realStartActivityLocked方法,真正启动Activity的方法。
五、启动Activity
经过一系列准备,终于到了真正启动Activity的时候了
1、ActivityStackSupervisor & 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);...}
这里面通过调用 app.thread的scheduleLaunchActivity来启动Activity。这里的thread是ActivityThread的内部类ApplicationThread。ApplicationThread也是一个Binder类。所以真正执行scheduleLaunchActivity方法的地方在ActivityThread的内部类ApplicationThread中。
2、ActivityThread & scheduleLaunchActivity()
@Overridepublic 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);}
这里面是一个Handler机制,我们来看接收消息的地方。
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;r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;}
执行handleLaunchActivity方法
3、ActivityThread & handleLaunchActivity()
...Activity a = performLaunchActivity(r, customIntent);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);...
然后执行performLaunchActivity方法启动Activity
4、ActivityThread & performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...Activity activity = null;try {java.lang.ClassLoader cl = r.packageInfo.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) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException("Unable to instantiate activity " + component+ ": " + e.toString(), e);}}...Application app = r.packageInfo.makeApplication(false, mInstrumentation);return activity;}
-
1、通过mInstrumentation.newActivity()方法,使用类加载器创建一个Activity
public Activity newActivity(ClassLoader cl, String className,Intent intent)throws InstantiationException, IllegalAccessException,ClassNotFoundException {return (Activity)cl.loadClass(className).newInstance(); }
-
2、通过makeApplication方法创建一个Application 对象
在callApplicationOnCreate方法中调用Application中调用onCreate()方法public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {//如果已经创建过了则直接返回if (mApplication != null) {return mApplication;}...Application app = null;String appClass = mApplicationInfo.className;if (forceDefaultAppClass || (appClass == null)) {appClass = "android.app.Application";}try {java.lang.ClassLoader cl = getClassLoader();if (!mPackageName.equals("android")) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"initializeJavaContextClassLoader");initializeJavaContextClassLoader();Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);} catch (Exception e) {...}mActivityThread.mAllApplications.add(app);mApplication = app;if (instrumentation != null) {try {instrumentation.callApplicationOnCreate(app);} catch (Exception e) {...}}...return app; }
public void callApplicationOnCreate(Application app) {app.onCreate();}
-
3、创建Context对象,并且调用Activity的attach()方法
Context appContext = createBaseContextForActivity(r, activity);CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());Configuration config = new Configuration(mCompatConfiguration);if (r.overrideConfig != null) {config.updateFrom(r.overrideConfig);}if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "+ r.activityInfo.name + " with config " + config);Window window = null;if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;}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);
-
4、调用Activity的onCreate()
Instrumentation类中callActivityOnCreate()if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}
Activity中performCreate()public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);activity.performCreate(icicle, persistentState);postPerformCreate(activity);}
final void performCreate(Bundle icicle) {restoreHasCurrentPermissionRequest(icicle);onCreate(icicle);mActivityTransitionState.readState(icicle);performCreateCommon(); }
-
5、Activity的onStart()
if (!r.activity.mFinished) {activity.performStart();r.stopped = false; } //Activity类中方法 final void performStart() {...mInstrumentation.callActivityOnStart(this); } //Instrumentation类 public void callActivityOnStart(Activity activity) {activity.onStart(); }
-
其他方法
- onRestoreInstanceState
if (!r.activity.mFinished) {if (r.isPersistable()) {if (r.state != null || r.persistentState != null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,r.persistentState);}} else if (r.state != null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);}}
到这里performLaunchActivity
的方法就执行完毕了。我们的新创建Activity已经经历了onCreate
和onStart
方法了。现在我们回到ActivityThread的handleLaunchActivity()中,执行完performLaunchActivity方法后,下面还有个handleResumeActivity();
方法。
ActivityThread & handleResumeActivity
final void handleResumeActivity(IBinder token,boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {...r = performResumeActivity(token, clearHide, reason);...}
继续执行performResumeActivity
ActivityThread & performResumeActivity
public final ActivityClientRecord performResumeActivity(IBinder token,boolean clearHide, String reason) {ActivityClientRecord r = mActivities.get(token);...r.activity.performResume();...}
同理,查看Activity的performResume
Activity& performResume()
final void performResume() {mInstrumentation.callActivityOnResume(this);...}
Instrumentation & callActivityOnResume
public void callActivityOnResume(Activity activity) {activity.mResumed = true;activity.onResume();...}
执行activity.onResume()
,到这里新的Activity已经显示在屏幕上,并可以与用户进行交互了。
六、栈顶Activity的onStop()
我们已经知道了栈顶Activity的onStop()方法是在新Activity的onResume()之后调用的。所以回到handleResumeActivity方法中去
1、ActivityThread & handleResumeActivity()
...Looper.myQueue().addIdleHandler(new Idler());...
在handleResumeActivity方法的尾部有上面的代码,查看Idler的具体实现
private class Idler implements MessageQueue.IdleHandler {@Overridepublic final boolean queueIdle() {ActivityClientRecord a = mNewActivities;if (a != null) {IActivityManager am = ActivityManagerNative.getDefault();ActivityClientRecord prev;do { if (a.activity != null && !a.activity.mFinished) {try {am.activityIdle(a.token, a.createdConfig, stopProfiling);a.createdConfig = null;} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}} while (a != null);} }}
因为ActivityManagerNative相等于ActivityManagerService的客户端,所以activityIdle
最终会在ActivityManagerService中执行
2、ActivityManagerService & activityIdle()
@Overridepublic final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {final long origId = Binder.clearCallingIdentity();synchronized (this) {ActivityStack stack = ActivityRecord.getStackLocked(token);if (stack != null) {ActivityRecord r =mStackSupervisor.activityIdleInternalLocked(token, false, config);if (stopProfiling) {if ((mProfileProc == r.app) && (mProfileFd != null)) {try {mProfileFd.close();} catch (IOException e) {}clearProfilerLocked();}}}}Binder.restoreCallingIdentity(origId);}
此方法会执行StackSupervisor.activityIdleInternalLocked()
3、StackSupervisor & activityIdleInternalLocked()
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,Configuration config) {...for (int i = 0; i < NS; i++) {r = stops.get(i);final ActivityStack stack = r.task.stack;if (stack != null) {if (r.finishing) {stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);} else {stack.stopActivityLocked(r);}}}...return r;}
此方法会执行ActivityStack.stopActivityLocked()
4、ActivityStack & stopActivityLocked
final void stopActivityLocked(ActivityRecord r) { ...r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);...}
通用调用了ActivityThread内部类ApplicationThread的scheduleStopActivity方法
5、ActivityThread & scheduleStopActivity
public final void scheduleStopActivity(IBinder token, boolean showWindow,int configChanges) {int seq = getLifecycleSeq();if (DEBUG_ORDER) Slog.d(TAG, "stopActivity " + ActivityThread.this+ " operation received seq: " + seq);sendMessage(showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,token, 0, configChanges, seq);}
同样适用handler机制。在接收消息的地方执行handleStopActivity方法
6、ActivityThread & handleStopActivity
private void handleStopActivity(IBinder token, boolean show, int configChanges, int seq) {ActivityClientRecord r = mActivities.get(token);if (!checkAndUpdateLifecycleSeq(seq, r, "stopActivity")) {return;}r.activity.mConfigChangeFlags |= configChanges;StopInfo info = new StopInfo();performStopActivityInner(r, info, show, true, "handleStopActivity");...}
然后执行performStopActivityInner()
private void performStopActivityInner(ActivityClientRecord r,StopInfo info, boolean keepShown, boolean saveState, String reason) {if (r != null) {// One must first be paused before stopped...performPauseActivityIfNeeded(r, reason);// Next have the activity save its current state and managed dialogs...if (!r.activity.mFinished && saveState) {if (r.state == null) {callCallActivityOnSaveInstanceState(r);}}if (!keepShown) {// Now we are idle.r.activity.performStop(false /*preserveWindow*/);}}}
这里面有两个逻辑,一个会执行onSaveInstanceState,另一个会执行performStop()来停止Activity。
7、Activity & performStop
final void performStop(boolean preserveWindow) {...mInstrumentation.callActivityOnStop(this);...}
同样在Instrumentation的callActivityOnStop方法中调用activity的onStop方法
public void callActivityOnStop(Activity activity) {activity.onStop();}
到这里Activity的启动流程就结束了。
总结
断断续续看了差不多两天,有时候看的头晕眼花了。还好总算把Activity的启动流程给过了一遍。中途迷失了好几次。
- Activity的启动流程是从startActivity或startActivityForResult开始的。Activity内部最终调用startActivityForResult方法
- Activity的启动流程涉及到多进程通信,通过Binder机制完成通信的。例如:ActivityThread 和 ActivityManagerService 之间的通信
- ActivityThread通过Binder线程池接收消息后,会通过Handler机制将其在主线程中回调。
- ActivityManagerService启动Activity的时候,先判断判断Activity所在进程是否创建,然后才执行启动流程
- ActivityManagerService会通过Socket与Zygote之间通信,通知Zygote进程fork出新的进程,然后执行ActivityThread的mani方法;
参考:
开发艺术探索
(Android 9.0)Activity启动流程源码分析
Android源码解析之(十四)–>Activity启动流程