总结 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 生命周期。