2.2Activity启动流程
目录介绍
- 01.Launcher启动开启Activity
- 02.查看startActivity方法
- 2.1 Activity.startActivity()
- 2.2 Activity.startActivityForResult
- 2.3 Instrumentation.execStartActivity
- 2.4 IActivityManager说明
- 2.5 ActivityManagerService介绍
- 03.ActivityManagerService详谈
- 04.执行栈顶Activity的onPause方法
- 05.启动Activity所属的应用进程
- 06.执行启动Activity重点逻辑
- 07.启动流程大概总结一下
01.Launcher启动开启Activity
- 这个首先看LauncherActivity类中的onListItemClick方法
- Launcher启动之后会将各个应用包名和icon与app的name保存起来,然后执行icon的点击事件的时候调用startActivity方法:
@Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent); } protected Intent intentForPosition(int position) { ActivityAdapter adapter = (ActivityAdapter) mAdapter; return adapter.intentForPosition(position); } public Intent intentForPosition(int position) { if (mActivitiesList == null) { return null; } Intent intent = new Intent(mIntent); ListItem item = mActivitiesList.get(position); intent.setClassName(item.packageName, item.className); if (item.extras != null) { intent.putExtras(item.extras); } return intent; }
- 可以发现,我们在启动Activity的时候,执行的逻辑就是创建一个Intent对象,然后初始化Intent对象,使用隐式启动的方式启动该Acvitity,这里为什么不能使用显示启动的方式呢?
- 这是因为Launcher程序启动的Activity一般都是启动一个新的应用进程,该进程与Launcher进程不是在同一个进程中,所以也就无法引用到启动的Activity字节码,自然也就无法启动该Activity了。
- 那么应用的图标是怎么和这个应用的Lancher Activity联系起来的呢?
- 系统在启动的时候会启动PackageManagerService(包管理服务),所有的应用都是通过它安装的,PackageManagerService会对应用的AndroidManifest.xml进行解析,从而得到应用里所有的组件信息。Lanucher组件在启动过程中就会去向PackageManagerService查询包含以下信息的Activity组件。
<intent-filter> <action android:text="android.intent.action.MAIN" /> <category android:text="android.intent.category.LAUNCHER" /> </intent-filter>
- 并为每一个包含该信息的Activity组件创建一个快捷图标,由此两者便建立了联系。
02.查看startActivity方法
- 查看startActivity方法的具体实现:
> MyActivity.startActivity() > Activity.startActivity() > Activity.startActivityForResult > Instrumentation.execStartActivty > ActivityManagerNative.getDefault().startActivityAsUser()
2.1 Activity.startActivity()
- 在我们的Activity中调用startActivity方法,会执行Activity中的startActivity
@Override public void startActivity(Intent intent) { this.startActivity(intent, null); }
- 然后在Activity中的startActivity方法体里调用了startActivity的重载方法,这里我们看一下其重载方法的实现:
@Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { startActivityForResult(intent, -1); } }
- 由于在上一步骤中我们传递的Bundle对象为空,所以这里我们执行的是else分支的逻辑,所以这里调用了startActivityForResult方法,并且传递的参数为intent和-1.
- 注意:通过这里的代码我们可以发现,其实我们在Activity中调用startActivity的内部也是调用的startActivityForResult的。那么为什么调用startActivityForResult可以在Activity中回调onActivityResult而调用startActivity则不可以呢?可以发现其主要的区别是调用startActivity内部调用startActivityForResult传递的传输requestCode值为-1,也就是说我们在Activity调用startActivityForResult的时候传递的requestCode值为-1的话,那么onActivityResult是不起作用的。
- 实际上,经测试requestCode的值小于0的时候都是不起作用的,所以当我们调用startActivityForResult的时候需要注意这一点。
2.2 Activity.startActivityForResult
- 我们继续往下看,startActivityForResult方法的具体实现:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { 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分之,然后调用mInstrumentation.execStartActivity方法,并且这里需要注意的是,有一个判断逻辑:
if (requestCode >= 0) { mStartedActivity = true; }
- 通过注释也验证了我们刚刚的说法即,调用startActivityForResult的时候只有requestCode的值大于等于0,onActivityResult才会被回调。
2.3 Instrumentation.execStartActivity
- 然后我们看一下mInstrumentation.execStartActivity方法的实现。
- 在查看execStartActivity方法之前,我们需要对mInstrumentation对象有一个了解?什么是Instrumentation?
- Instrumentation是android系统中启动Activity的一个实际操作类,也就是说Activity在应用进程端的启动实际上就是Instrumentation执行的,那么为什么说是在应用进程端的启动呢?
- 实际上activity的启动分为应用进程端的启动和SystemServer服务进程端的启动的,多个应用进程相互配合最终完成了Activity在系统中的启动的,而在应用进程端的启动实际的操作类就是Instrumentation来执行的,可能还是有点绕口,没关系,随着我们慢慢的解析大家就会对Instrumentation的认识逐渐加深的。
- 可以发现execStartActivity方法传递的几个参数:
this,为启动Activity的对象; contextThread,为Binder对象,是主进程的context对象; token,也是一个Binder对象,指向了服务端一个ActivityRecord对象; target,为启动的Activity; intent,启动的Intent对象; requestCode,请求码; options,参数;
- 这样就调用了Instrument.execStartActivity方法了:
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(); 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; }
- 我们发现在这个方法中主要调用ActivityManagerNative.getDefault().startActivity方法,那么ActivityManagerNative又是个什么鬼呢?查看一下getDefault()对象的实现:
static public IActivityManager getDefault() { return gDefault.get(); }
- 好吧,相当之简单直接返回的是gDefault.get(),那么gDefault又是什么呢?
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; } };
- 可以发现启动过asInterface()方法创建,然后我们继续看一下asInterface方法的实现:
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); }
- 最后直接返回一个ActivityManagerProxy对象,而ActivityManagerProxy继承与IActivityManager,到了这里就引出了我们android系统中很重要的一个概念:Binder机制。
2.4 IActivityManager说明
- 我们知道应用进程与SystemServer进程属于两个不同的进程,进程之间需要通讯,android系统采取了自身设计的Binder机制,这里的ActivityManagerProxy和ActivityManagerNative都是继承与IActivityManager的而SystemServer进程中的ActivityManagerService对象则继承与ActivityManagerNative。
- 简单的表示:Binder接口 --> ActivityManagerNative/ActivityManagerProxy --> ActivityManagerService;
- 这样,ActivityManagerNative与ActivityManagerProxy相当于一个Binder的客户端而ActivityManagerService相当于Binder的服务端,这样当ActivityManagerNative调用接口方法的时候底层通过Binder driver就会将请求数据与请求传递给server端,并在server端执行具体的接口逻辑。需要注意的是Binder机制是单向的,是异步的,也就是说只能通过client端向server端传递数据与请求而不同等待服务端的返回,也无法返回,那如果SystemServer进程想向应用进程传递数据怎么办?这时候就需要重新定义一个Binder请求以SystemServer为client端,以应用进程为server端,这样就是实现了两个进程之间的双向通讯。
2.5 ActivityManagerService
- 说了这么多我们知道这里的ActivityManagerNative是ActivityManagerService在应用进程的一个client就好了,通过它就可以滴啊用ActivityManagerService的方法了。
- 继续往下卡,我们调用的是:
int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
- 这里通过我们刚刚的分析,ActivityManagerNative.getDefault()方法会返回一个ActivityManagerProxy对象,那么我们看一下ActivityManagerProxy对象的startActivity方法:
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; }
- 这里就涉及到了具体的Binder数据传输机制了,我们不做过多的分析,知道通过数据传输之后就会调用SystemServer进程的ActivityManagerService的startActivity就好了。
03.ActivityManagerService详谈
- ActivityManagerService接收启动Activity的请求
> ActivityManagerService.startActivity() > ActvityiManagerService.startActivityAsUser() > ActivityStackSupervisor.startActivityMayWait() > ActivityStackSupervisor.startActivityLocked() > ActivityStackSupervisor.startActivityUncheckedLocked() > ActivityStackSupervisor.startActivityLocked() > ActivityStackSupervisor.resumeTopActivitiesLocked() > ActivityStackSupervisor.resumeTopActivityInnerLocked()
3.1 ActivityManagerService.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 options) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId()); }
- 可以看到,该方法并没有实现什么逻辑,直接调用了startActivityAsUser方法,我们继续看一下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 options, int userId) { enforceNotIsolatedCaller("startActivity"); userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, false, userId, null, null); }
- 可以看到这里只是进行了一些关于userid的逻辑判断,然后就调用mStackSupervisor.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 config, Bundle options, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask) { int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask); return res; }
- 这个方法中执行了启动Activity的一些其他逻辑判断,在经过判断逻辑之后调用startActivityLocked方法:
final int startActivityLocked(IApplicationThread caller, Intent intent, String resolvedType, ActivityInfo aInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, Bundle options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container, TaskRecord inTask) { int err = ActivityManager.START_SUCCESS; err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask); return err; }
- 这个方法中主要构造了ActivityManagerService端的Activity对象-->ActivityRecord,并根据Activity的启动模式执行了相关逻辑。然后调用了startActivityUncheckedLocked方法:
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, Bundle options, TaskRecord inTask) { ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); targetStack.mLastPausedActivity = null; targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); if (!launchTaskBehind) { // Don't set focus on an activity that's going to the back. mService.setFocusedActivityLocked(r, "startedActivity"); } return ActivityManager.START_SUCCESS; }
- startActivityUncheckedLocked方法中只要执行了不同启动模式不同栈的处理,并最后调用了startActivityLocked的重载方法:
final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition, Bundle options) { ... if (doResume) { mStackSupervisor.resumeTopActivitiesLocked(this, r, options); } }
- 这个startActivityLocked方法主要执行初始化了windowManager服务,然后调用resumeTopActivitiesLocked方法:
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions) { if (targetStack == null) { targetStack = mFocusedStack; } // Do targetStack first. boolean result = false; if (isFrontStack(targetStack)) { result = targetStack.resumeTopActivityLocked(target, targetOptions); } for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (stack == targetStack) { continue; } if (isFrontStack(stack)) { stack.resumeTopActivityLocked(null); } } } return result; }
- 可以发现经过循环逻辑判断之后,最终调用了resumeTopActivityLocked方法:
final boolean resumeTopActivityLocked(ActivityRecord prev) { return resumeTopActivityLocked(prev, null); }
- 然后调用:
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (mStackSupervisor.inResumeTopActivity) { // Don't even start recursing. return false; } boolean result = false; try { // Protect against recursion. mStackSupervisor.inResumeTopActivity = true; if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) { mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN; mService.updateSleepIfNeededLocked(); } result = resumeTopActivityInnerLocked(prev, options); } finally { mStackSupervisor.inResumeTopActivity = false; } return result; }
- 继续调用resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); } ... return true; }
04.执行栈顶Activity的onPause方法
- 经过一系列处理逻辑之后最终调用了startPausingLocked方法,这个方法作用就是让系统中栈中的Activity执行onPause方法。
>ActivityStack.startPausingLocked() >IApplicationThread.schudulePauseActivity() >ActivityThread.sendMessage() >ActivityThread.H.sendMessage(); >ActivityThread.H.handleMessage() >ActivityThread.handlePauseActivity() >ActivityThread.performPauseActivity() >Activity.performPause() >Activity.onPause() >ActivityManagerNative.getDefault().activityPaused(token) >ActivityManagerService.activityPaused() >ActivityStack.activityPausedLocked() >ActivityStack.completePauseLocked() >ActivityStack.resumeTopActivitiesLocked() >ActivityStack.resumeTopActivityLocked() >ActivityStack.resumeTopActivityInnerLocked() >ActivityStack.startSpecificActivityLocked
- 好吧,方法比较多也比较乱,首先来看startPausingLocked方法:
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) { ... if (prev.app != null && prev.app.thread != null) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); try { EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, prev.userId, System.identityHashCode(prev), prev.shortComponentName); mService.updateUsageStats(prev, false); prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. Slog.w(TAG, "Exception thrown during pause", e); mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } } else { mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } ... }
- 可以看到这里执行了pre.app.thread.schedulePauseActivity方法,通过分析不难发现这里的thread是一个IApplicationThread类型的对象,而在ActivityThread中也定义了一个ApplicationThread的类,其继承了IApplicationThread,并且都是Binder对象,不难看出这里的IAppcation是一个Binder的client端而ActivityThread中的ApplicationThread是一个Binder对象的server端,所以通过这里的thread.schedulePauseActivity实际上调用的就是ApplicationThread的schedulePauseActivity方法。
- 这里的ApplicationThread可以和ActivityManagerNative对于一下:
- 通过ActivityManagerNative-->ActivityManagerService实现了应用进程与SystemServer进程的通讯。通过AppicationThread——IApplicationThread实现了SystemServer进程与应用进程的通讯。
- 然后我们继续看一下ActivityThread中schedulePauseActivity的具体实现:
public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { sendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? 1 : 0) | (dontReport ? 2 : 0), configChanges); }
- 发送了PAUSE_ACTIVITY_FINISHING消息,然后看一下sendMessage的实现方法:
private void sendMessage(int what, Object obj, int arg1, int arg2) { sendMessage(what, obj, arg1, arg2, false); }
- 调用了其重载方法:
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj); 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的sendMessage方法,mH是在ActivityThread中定义的一个Handler对象,主要处理SystemServer进程的消息,我们看一下其handleMessge方法的实现:
public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { ... case PAUSE_ACTIVITY_FINISHING: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&1) != 0); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... }
- 可以发现其调用了handlePauseActivity方法:
private void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) { ActivityClientRecord r = mActivities.get(token); 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()); // 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) { } } mSomeActivitiesChanged = true; } }
- 然后在方法体内部通过调用performPauseActivity方法来实现对栈顶Activity的onPause生命周期方法的回调,可以具体看一下他的实现:
final Bundle performPauseActivity(IBinder token, boolean finished, boolean saveState) { ActivityClientRecord r = mActivities.get(token); return r != null ? performPauseActivity(r, finished, saveState) : null; }
- 然后调用其重载方法:
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, boolean saveState) { ... mInstrumentation.callActivityOnPause(r.activity); ... return !r.activity.mFinished && saveState ? r.state : null; }
- 这样回到了mInstrumentation的callActivityOnPuase方法:
public void callActivityOnPause(Activity activity) { activity.performPause(); }
- 原来最终回调到了Activity的performPause方法:
final void performPause() { mDoReportFullyDrawn = false; mFragments.dispatchPause(); mCalled = false; onPause(); mResumed = false; if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); } mResumed = false; }
- 终于,回调到了Activity的onPause方法,Activity生命周期中的第一个生命周期方法终于被我们找到了。。。。也就是说我们在启动一个Activity的时候最先被执行的是栈顶的Activity的onPause方法。记住这点吧,面试的时候经常会问到类似的问题。
- 然后回到我们的handlePauseActivity方法
- 在该方法的最后面执行了ActivityManagerNative.getDefault().activityPaused(token);方法,这是应用进程告诉服务进程,栈顶Activity已经执行完成onPause方法了,通过前面我们的分析,我们知道这句话最终会被ActivityManagerService的activityPaused方法执行。
@Override public final void activityPaused(IBinder token) { final long origId = Binder.clearCallingIdentity(); synchronized(this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { stack.activityPausedLocked(token, false); } } Binder.restoreCallingIdentity(origId); }
- 可以发现,该方法内部会调用ActivityStack的activityPausedLocked方法,好吧,继续看一下activityPausedLocked方法的实现:
final void activityPausedLocked(IBinder token, boolean timeout) { if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r + (timeout ? " (due to timeout)" : " (pause complete)")); completePauseLocked(true); }
- 然后执行了completePauseLocked方法:
private void completePauseLocked(boolean resumeNext) { if (resumeNext) { final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!mService.isSleepingOrShuttingDown()) { mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null); } else { mStackSupervisor.checkReadyForSleepLocked(); ActivityRecord top = topStack.topRunningActivityLocked(null); if (top == null || (prev != null && top != prev)) { mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null); } } } }
- 经过了一系列的逻辑之后,又调用了resumeTopActivitiesLocked方法,又回到了第二步中解析的方法中了,这样经过
resumeTopActivitiesLocked --> ActivityStack.resumeTopActivityLocked() --> resumeTopActivityInnerLocked --> startSpecificActivityLocked
- 我们看一下startSpecificActivityLocked的具体实现:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { 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)) { 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所需要的应用进程是否已经启动,若启动的话,则直接调用realStartAtivityLocked方法,否则调用startProcessLocked方法,用于启动应用进程。
- 这样关于启动Activity时的第三步骤就已经执行完成了,这里主要是实现了对栈顶Activity执行onPause方法,而这个方法首先判断需要启动的Activity所属的进程是否已经启动,若已经启动则直接调用启动Activity的方法,否则将先启动Activity的应用进程,然后在启动该Activity。
06.执行启动Activity重点逻辑
- 大概流程如下所示
ActivityStackSupervisor.attachApplicationLocked() ActivityStackSupervisor.realStartActivityLocked() IApplicationThread.scheduleLauncherActivity() ActivityThread.sendMessage() ActivityThread.H.sendMessage() ActivityThread.H.handleMessage() ActivityThread.handleLauncherActivity() ActivityThread.performLauncherActivity() Instrumentation.callActivityOnCreate() Activity.onCreate() ActivityThread.handleResumeActivity() ActivityThread.performResumeActivity() Activity.performResume() Instrumentation.callActivityOnResume() Activity.onResume() ActivityManagerNative.getDefault().activityResumed(token)
- 首先看一下attachApplicationLocked方法的实现:
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } ActivityRecord hr = stack.topRunningActivityLocked(null); if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + hr.intent.getComponent().flattenToShortString(), e); throw e; } } } } } if (!didSomething) { ensureActivitiesVisibleLocked(null, 0); } return didSomething; }
- 可以发现其内部调用了realStartActivityLocked方法,通过名字可以知道这个方法应该就是用来启动Activity的,看一下这个方法的实现逻辑:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { app.forceProcessStateUpTo(mService.mTopProcessState); app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); return true; }
- 可以发现与第三步执行栈顶Activity onPause时类似,这里也是通过调用IApplicationThread的方法实现的,这里调用的是scheduleLauncherActivity方法,所以真正执行的是ActivityThread中的scheduleLauncherActivity,所以我们看一下ActivityThread中的scheduleLauncherActivity的实现:
@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); }
- 还是那套逻辑,ActivityThread接收到SystemServer进程的消息之后会通过其内部的Handler对象分发消息,经过一系列的分发之后调用了ActivityThread的handleLaunchActivity方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); } }
- 可以发现这里调用了performLauncherActivity,看名字应该就是执行Activity的启动操作了。。。
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); } } activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } return activity; }
- 可以发现这里我们需要的Activity对象终于是创建出来了,而且他是以反射的机制创建的,现在还不太清楚为啥google要以反射的方式创建Activity,先不看这些,然后在代码中其调用Instrumentation的callActivityOnCreate方法。
public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); activity.performCreate(icicle); postPerformCreate(activity); }
- 然后执行activity的performCreate方法。。。
final void performCreate(Bundle icicle) { onCreate(icicle); mActivityTransitionState.readState(icicle); performCreateCommon(); }
- 在回到我们的performLaunchActivity方法,其在调用了mInstrumentation.callActivityOnCreate方法之后又调用了activity.performStart();方法,好吧,看一下他的实现方式:
final void performStart() { mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions()); mFragments.noteStateNotSaved(); mCalled = false; mFragments.execPendingActions(); mInstrumentation.callActivityOnStart(this); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onStart()"); } mFragments.dispatchStart(); mFragments.reportLoaderStart(); mActivityTransitionState.enterReady(this); }
- 还是通过Instrumentation调用callActivityOnStart方法:
public void callActivityOnStart(Activity activity) { activity.onStart(); }
- 还是回到我们刚刚的handleLaunchActivity方法,在调用完performLaunchActivity方法之后,其有吊用了handleResumeActivity方法,好吧,看名字应该是回调Activity的onResume方法的。
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; // TODO Push resumeArgs into the activity for consideration ActivityClientRecord r = performResumeActivity(token, clearHide); if (r != null) { final Activity a = r.activity; if (localLOGV) Slog.v( TAG, "Resume " + r + " started activity: " + a.mStartedActivity + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; // If the window hasn't yet been added to the window manager, // and this guy didn't finish itself or start another activity, // then go ahead and add the window. boolean willBeVisible = !a.mStartedActivity; if (!willBeVisible) { try { willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( a.getActivityToken()); } catch (RemoteException e) { } } if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; wm.addView(decor, l); } // If the window has already been added, but during resume // we started another activity, then don't yet make the // window visible. } else if (!willBeVisible) { if (localLOGV) Slog.v( TAG, "Launch " + r + " mStartedActivity set"); r.hideForNow = true; } // Get rid of anything left hanging around. cleanUpPendingRemoveWindows(r); // The window is now visible if it has been added, we are not // simply finishing, and we are not starting another activity. if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { r.tmpConfig.setTo(r.newConfig); if (r.overrideConfig != null) { r.tmpConfig.updateFrom(r.overrideConfig); } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.tmpConfig); performConfigurationChanged(r.activity, r.tmpConfig); freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); r.newConfig = null; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); WindowManager.LayoutParams l = r.window.getAttributes(); if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) { l.softInputMode = (l.softInputMode & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) | forwardBit; if (r.activity.mVisibleFromClient) { ViewManager wm = a.getWindowManager(); View decor = r.window.getDecorView(); wm.updateViewLayout(decor, l); } } r.activity.mVisibleFromServer = true; mNumVisibleActivities++; if (r.activity.mVisibleFromClient) { r.activity.makeVisible(); } } if (!r.onlyLocalRequest) { r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v( TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler(new Idler()); } r.onlyLocalRequest = false; // Tell the activity manager we have resumed. if (reallyResume) { try { ActivityManagerNative.getDefault().activityResumed(token); } catch (RemoteException ex) { } } } else { // If an exception was thrown when trying to resume, then // just end this activity. try { ActivityManagerNative.getDefault() .finishActivity(token, Activity.RESULT_CANCELED, null, false); } catch (RemoteException ex) { } } }
- 可以发现其resumeActivity的逻辑调用到了performResumeActivity方法,我们来看一下performResumeActivity是如何实现的。
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide) { ActivityClientRecord r = mActivities.get(token); if (localLOGV) Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished); if (r != null && !r.activity.mFinished) { if (clearHide) { r.hideForNow = false; r.activity.mStartedActivity = false; } try { r.activity.onStateNotSaved(); r.activity.mFragments.noteStateNotSaved(); if (r.pendingIntents != null) { deliverNewIntents(r, r.pendingIntents); r.pendingIntents = null; } if (r.pendingResults != null) { deliverResults(r, r.pendingResults); r.pendingResults = null; } r.activity.performResume(); EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(), r.activity.getComponentName().getClassName()); r.paused = false; r.stopped = false; r.state = null; r.persistentState = null; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( "Unable to resume activity " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } } return r; }
- 在方法体中,最终调用了r.activity.performResume();方法,好吧,这个方法是Activity中定义的方法,我们需要在Activity中查看这个方法的具体实现:
final void performResume() { ... mInstrumentation.callActivityOnResume(this); ... }
- 又是熟悉的味道,通过Instrumentation来调用了callActivityOnResume方法。。。
public void callActivityOnResume(Activity activity) { activity.mResumed = true; activity.onResume(); if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); am.match(activity, activity, activity.getIntent()); } } } }
07.启动流程大概总结一下
- 大概如下所示
- Activity的启动流程一般是通过调用startActivity或者是startActivityForResult来开始的
- startActivity内部也是通过调用startActivityForResult来启动Activity,只不过传递的requestCode小于0
- Activity的启动流程涉及到多个进程之间的通讯这里主要是ActivityThread与ActivityManagerService之间的通讯
- ActivityThread向ActivityManagerService传递进程间消息通过ActivityManagerNative,ActivityManagerService向ActivityThread进程间传递消息通过IApplicationThread。
- ActivityManagerService接收到应用进程创建Activity的请求之后会执行初始化操作,解析启动模式,保存请求信息等一系列操作。
- ActivityManagerService保存完请求信息之后会将当前系统栈顶的Activity执行onPause操作,并且IApplication进程间通讯告诉应用程序继承执行当前栈顶的Activity的onPause方法;
- ActivityThread接收到SystemServer的消息之后会统一交个自身定义的Handler对象处理分发;
- ActivityThread执行完栈顶的Activity的onPause方法之后会通过ActivityManagerNative执行进程间通讯告诉ActivityManagerService,栈顶Actiity已经执行完成onPause方法,继续执行后续操作;
- ActivityManagerService会继续执行启动Activity的逻辑,这时候会判断需要启动的Activity所属的应用进程是否已经启动,若没有启动则首先会启动这个Activity的应用程序进程;
- ActivityManagerService会通过socket与Zygote继承通讯,并告知Zygote进程fork出一个新的应用程序进程,然后执行ActivityThread的mani方法;
- 在ActivityThread.main方法中执行初始化操作,初始化主线程异步消息,然后通知ActivityManagerService执行进程初始化操作;
- ActivityManagerService会在执行初始化操作的同时检测当前进程是否有需要创建的Activity对象,若有的话,则执行创建操作;
- ActivityManagerService将执行创建Activity的通知告知ActivityThread,然后通过反射机制创建出Activity对象,并执行Activity的onCreate方法,onStart方法,onResume方法;
- ActivityThread执行完成onResume方法之后告知ActivityManagerService onResume执行完成,开始执行栈顶Activity的onStop方法;
- ActivityManagerService开始执行栈顶的onStop方法并告知ActivityThread;
- ActivityThread执行真正的onStop方法;
其他介绍
01.关于博客汇总链接
02.关于我的博客
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/yczbj/activities
- 简书:http://www.jianshu.com/u/b7b2c6ed9284
- csdn:http://my.csdn.net/m0_37700275
- 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
- 开源中国:https://my.oschina.net/zbj1618/blog
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles
- 掘金:https://juejin.im/user/5939433efe88c2006afa0c6e