@Override public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) { // 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 //此处会回调Activity的onResume方法,而视图相关代码还在下面。 //拿到ActivityRecord关键点在一个token,可以理解为Activity在ActivityThread中保存的令牌,本身是个Binder,因为ActivityThread有个成员变量mActivities,专门用来存储此进程中使用的Activity。 //具体如何放进去呢?可以参考Activity启动流程。 final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); if (r == null ) { // We didn't actually resume the activity, so skipping any follow-up actions. return ; } if (mActivitiesToBeDestroyed.containsKey(token)) { // Although the activity is resumed, it is going to be destroyed. So the following // UI operations are unnecessary and also prevents exception because its token may // be gone that window manager cannot recognize it. All necessary cleanup actions // performed below will be done while handling destruction. return ; } final Activity a = r.activity; //拿到Activity,ActivityRecord是事实上的窗口。 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 = ActivityTaskManager.getService().willActivityBeVisible( a.getActivityToken()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } // 此处,就是和视图相关的代码了 if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); //拿到window,此处实例是PhoneWindow View decor = r.window.getDecorView(); // 拿到顶层容器 decor.setVisibility(View.INVISIBLE); //先设置不可见,在后面makeVisible函数才显示可见 ViewManager wm = a.getWindowManager(); // wm WindowManager.LayoutParams l = r.window.getAttributes(); //布局参数 a.mDecor = decor; // Activity 和 Decor建立联系 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; // 窗口类型:默认为应用级别 l.softInputMode |= forwardBit; if (r.mPreserveWindow) { a.mWindowAdded = true ; r.mPreserveWindow = false ; // Normally the ViewRoot sets up callbacks with the Activity // in addView->ViewRootImpl#setView. If we are instead reusing // the decor view we have to notify the view root that the // callbacks may have changed. ViewRootImpl impl = decor.getViewRootImpl(); // 主角来了,ViewRootImpl! if (impl != null ) { impl.notifyChildRebuilt(); } } if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true ; //关键,将decor放入window中!具体实现类在WindowManagerImpl,然后用WindowManagerGlobal全局类委托给ViewRootImpl进行具体三个过程。 wm.addView(decor, l); } else { // The activity will get a callback for this {@link LayoutParams} change // earlier. However, at that time the decor will not be set (this is set // in this method), so no action will be taken. This call ensures the // callback occurs with the decor set. a.onWindowAttributesChanged(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, false /* force */ ); // 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 ) { performConfigurationChangedForActivity(r, r.newConfig); if (DEBUG_CONFIGURATION) { Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); } r.newConfig = null ; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward); ViewRootImpl impl = r.window.getDecorView().getViewRootImpl(); WindowManager.LayoutParams l = impl != null ? impl.mWindowAttributes : 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(); //执行此处,使得Decor对用户可见,但还未立即可见。 } } r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r); Looper.myQueue().addIdleHandler( new Idler()); } |