总结 startSpecificActivityLocked ——> realStartActivityLocked 设置 LaunchActivityItem 和 ResumeActivityItem——> IApplicationThread. scheduleTransaction ()
sendMessage ——> EXECUTE_TRANSACTION (也是打开 activity 的 H)——>execute——> executeCallbacks (onCreate)——>cycleToPath (onStart )——>performLifecycleSequence ——>handleResumeActivity ——> onResume
AMS [[2-Activity进程启动流程#第二步]]
startActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 final boolean realStartActivityLocked (ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ...... final ClientTransaction clientTransaction = ClientTransaction.obtain (app. thread, r.appToken); clientTransaction.addCallback (LaunchActivityItem.obtain (new ... final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain (mService.isNextTransitionForward ()); } else { lifecycleItem = PauseActivityItem.obtain (); } clientTransaction.setLifecycleStateRequest (lifecycleItem); mService.getLifecycleManager (). scheduleTransaction (clientTransaction); ...... return true ; }
addCallback()
传入的参数是 LaunchActivityItem
, 正是 ClientTransactionItem
的实现类。
setLifecycleStateRequest
表示当前的 ClientTransaction 执行之后应该处于的最终生命周期状态 (ResumeActivityItem)。
mService.getLifecycleManager()
返回的是 ClientLifecycleManager
对象,是 Android 9.0 新增的辅助处理生命周期的类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 > ClientLifecycleManager.java void scheduleTransaction (ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { transaction.recycle(); } } > ClientTransaction.java public void schedule () throws RemoteException { mClient.scheduleTransaction(this ); }
首先明确一点,到目前为止的方法调用都处于 AMS 所在进程,并不是我们的应用进程,会调用到 App 的 ApplicationThread
回到 App 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private class ApplicationThread extends IApplicationThread .Stub { ...... @Override public void scheduleTransaction (ClientTransaction transaction) throws RemoteException { ActivityThread.this .scheduleTransaction(transaction); } ...... } > ClientTransactionHandler.java void scheduleTransaction (ClientTransaction transaction) { transaction.preExecute(this );java sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); }
H 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class H extends Handler { public void handleMessage (Message msg) { ...... case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); if (isSystem()) { transaction.recycle(); } break ; ...... } }
TransactionExecutor 1 2 3 4 5 public void execute (ClientTransaction transaction) { executeCallbacks (transaction); executeLifecycleState (transaction); }
addCallback () >>> executeCallbacks () setLifecycleStateRequest >>> executeLifecycleState ()
executeCallbacks ()
会执行 addCallback ()
方法添加的生命周期回调。当前添加的是 LaunchActivityItem
。
executeLifecycleState ()
方法会将当前生命周期同步到 setLifecycleStateRequest ()
方法设置的生命周期状态。当前设置的是 ResumeActivityItem
。
onCreate TransactionExecutor.executeCallbacks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 > TransactionExecutor. java public void executeCallbacks (ClientTransaction transaction) { final List<ClientTransactionItem> callbacks = transaction.getCallbacks (); ...... final int size = callbacks.size (); for (int i = 0 ; i < size; ++i) { final ClientTransactionItem item = callbacks.get (i); ...... item.execute (mTransactionHandler, token, mPendingActions); item.postExecute (mTransactionHandler, token, mPendingActions); ...... } }
调用 XXXActivityItem
的 execute ()
和 postExecute ()
方法。例如:LaunchActivityItem、ActivityResultItem 等等,execute ()
方法中会 Binder 调用 ActivityThread
中对应的 handleXXXActivity ()
方法,performXXXXActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 > ActivityThread.java private Activity performLaunchActivity (ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null ; java.lang.ClassLoader cl = appContext.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); if (activity != null ) { activity.attach(appContext, this , getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embedded CID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window, r.configCallback); int theme = r.activityInfo.getThemeResource(); if (theme != 0 ) { activity.setTheme(theme); } activity.mCalled = false ; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } r.activity = activity; } r.setState(ON_CREATE); mActivities.put(r.token, r); return activity; }
callActivityOnCreate >>> performCreate >>> 最后调用 onCreate
onResume 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 > TransactionExecutor.java private void executeLifecycleState (ClientTransaction transaction) { final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); if (lifecycleItem == null ) { return ; } ...... cycleToPath(r, lifecycleItem.getTargetState(), true ); lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); }
现在是 ResumeActivityItem,方法体内直接调用其 execute()
方法。和 onCreate()
的套路是一模一样的,调用 ActivityThread.handleResumeActivity()
,接着是 Instrumentation.callActivityOnResume()
,最后回调 Activity.onResume()
。
onStart cycleToPath
正常的生命周期流程应该是 onCreate () -> onStart () -> onResume ()
,但是代码中好像又没有显示调用。其实是在 executeLifecycleState ()
中的 cycleToPath ()
方法中做了生命周期的同步。简单说就是,当前处于 onCreate ()
状态,setLifecycleState ()
设置的 final state 是 onResume () ,就需要执行 onCreate 到 onResume 之间的状态,即 onStart ()
。
getLifecyclePath
计算出中间的生命周期
onPause 在 resumeTopActivityInnerLocked
中会先对 resume 状态的 activity 执行 pause。
为什么 Activity.finish() 之后 10s 才 onDestroy ? Activity 的 onStop/onDestroy 是依赖 IdleHandler 来回调的,正常情况下当主线程空闲时会调用 。但是由于某些特殊场景下的问题,导致主线程迟迟无法空闲,onStop/onDestroy 也会迟迟得不到调用。但这并不意味着 Activity 永远得不到回收,系统提供了一个兜底机制,当 onResume 回调 10s 之后,如果仍然没有得到调用,会主动触发。
虽然有兜底机制,但无论如何这肯定不是我们想看到的。如果我们项目中的 onStop/onDestroy 延迟了 10s 调用,该如何排查问题呢?可以利用 Looper.getMainLooper().setMessageLogging()
方法,打印出主线程消息队列中的消息。每处理一条消息,都会打印如下内容:
1 2 logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
另外,由于 onStop/onDestroy
调用时机的不确定性,在做资源释放等操作的时候,一定要考虑好,以避免产生资源没有及时释放的情况。 不要做耗时操作,例如:循环动画
是谁指挥着 onStop/onDestroy 的调用? 在 Activity 跳转过程中,为了保证流畅的用户体验,只要前一个 Activity 与用户不可交互,即 onPause() 被回调之后,下一个 Activity 就要开始自己的生命周期流程了。所以 onStop/onDestroy
的调用时间是不确定的,甚至像文章开头的例子中,整整过了 10s 才回调。那么,到底是由谁来驱动 onStop/onDestroy
的执行呢?我们来看看下一个 Activity 的 onResume 过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 > ActivityThread.javapublic void handleResumeActivity (IBinder token, boolean finalStateRequest, boolean isForward, String reason) { ...... final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); ...... final Activity a = r.activity; ...... if (r.window == null && !a.mFinished && willBeVisible) { ...... if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true ; wm.addView(decor, l); } else { a.onWindowAttributesChanged(l); } } } else if (!willBeVisible) { ...... } ...... Looper.myQueue().addIdleHandler(new Idler ()); }
IdleHandler 在完成最终的界面绘制和显示之后,有这么一句代码 Looper.myQueue().addIdleHandler(new Idler())
。IdleHandler
不知道大家是否熟悉,它提供了一种机制,当主线程消息队列空闲时,会执行 IdleHandler 的回调方法。至于怎么算 “空闲”,我们可以看一下 MessageQueue.next()
方法。
[[IdleHandler]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 > MessageQueue.java Message next () { ...... int pendingIdleHandlerCount = -1 ; int nextPollTimeoutMillis = 0 ; for (;;) { nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this ) { Message prevMsg = null ; Message msg = mMessages; if (msg != null && msg.target == null ) { do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } if (msg != null ) { if (now < msg.when) { nextPollTimeoutMillis = (int ) Math.min(msg.when - now, Integer.MAX_VALUE); } else { mBlocked = false ; if (prevMsg != null ) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null ; msg.markInUse(); return msg; } } else { nextPollTimeoutMillis = -1 ; } ...... if (pendingIdleHandlerCount < 0 && (mMessages == null || now < mMessages.when)) { pendingIdleHandlerCount = mIdleHandlers.size(); } if (pendingIdleHandlerCount <= 0 ) { mBlocked = true ; continue ; } if (mPendingIdleHandlers == null ) { mPendingIdleHandlers = new IdleHandler [Math.max(pendingIdleHandlerCount, 4 )]; } mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers); } for (int i = 0 ; i < pendingIdleHandlerCount; i++) { final IdleHandler idler = mPendingIdleHandlers[i]; mPendingIdleHandlers[i] = null ; boolean keep = false ; try { keep = idler.queueIdle(); } catch (Throwable t) { Log.wtf(TAG, "IdleHandler threw exception" , t); } if (!keep) { synchronized (this ) { mIdleHandlers.remove(idler); } } } pendingIdleHandlerCount = 0 ; nextPollTimeoutMillis = 0 ; } }
在正常的消息处理机制之后,额外对 IdleHandler 进行了处理。当本次取到的 Message 为空或者需要延时处理的时候,就会去执行 mIdleHandlers
数组中的 IdleHandler 对象。其中还有一些关于 pendingIdleHandlerCount 的额外逻辑来防止循环处理。
当新的 Activity 完成页面绘制并显示之后,主线程就可以停下歇一歇,来执行 IdleHandler
了。再回来 handleResumeActivity()
中来,Looper.myQueue().addIdleHandler(new Idler())
,这里的 Idler
是 IdleHandler
的一个具体实现类。
最后获取要 stop 的 Activity,该 stop 的 stop,该 destroy 的 destroy
stop 和 destroy 系统10s兜底 在 ActivityRecord.completeResumeLocked
会在 activity resume 之后调用,在这个方法中会调用 ActivityStackSuperVisor.scheduleIdleTimeoutLocked(),即使主线程迟迟没有机会执行 Idler,系统仍然提供了兜底机制,防止已经不需要的 Activity 长时间无法被回收,从而造成内存泄漏等问题。 `
1 2 3 4 5 6 7 > ActivityStackSuperVisor.javavoid scheduleIdleTimeoutLocked(ActivityRecord next ) { Message msg = mHandler.obtainMessage(IDLE_TIMEOUT_MSG, next ); mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT); }
总结 应用进程发起请求 -> AMS
处理请求(对 Activity
发起 pause
生命周期) -> 应用进程处理 pause
生命周期 (处理完成后通知 AMS
) -> AMS
预处理 finishing 的 Activity
(将 Activity
添加至 stop
队列中,开启一个 10s 延迟任务) -> AMS
resume
一个新的 Activity
-> 应用进程执行新 Activity
的 resume
生命周期,完成后开启一个 IdleHandler
(IdleHandler
执行时会通知 AMS
) -> AMS
处理 stop
列表中的 Activity
(首先清除前面的延迟任务,然后发送 destory
生命周期到应用进程)-> 应用进程处理 destroy
生命周期。