publicabstractclassWindow { ... /** * Set the window manager for use by this Window to, for example, * display panels. This is <em>not</em> used for displaying the * Window itself -- that must be done by the client. * * @param wm The window manager for adding new windows. */ publicvoidsetWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { mAppToken = appToken; mAppName = appName; // 默认关闭硬件加速 mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false); // 如果传入的 WindowManager 为空,则通过 getSystemService 获取 WindowManager。 if (wm == null) { wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } // 将 WindowManager 和 Window 绑定,创建一个 WindowManagerImpl mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); } }
if (localLOGV) Slog.v(TAG, "Performing launch of " + r); if (localLOGV) Slog.v( TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir());
if (activity != null) { CharSequencetitle= r.activityInfo.loadLabel(appContext.getPackageManager()); Configurationconfig=newConfiguration(mCompatConfiguration); if (r.overrideConfig != null) { config.updateFrom(r.overrideConfig); } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); Windowwindow=null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; }
// Activity resources must be initialized with the same loaders as the // application context. appContext.getResources().addLoaders( app.getResources().getLoaders().toArray(newResourcesLoader[0]));
// 调用 Activity.onCreate() 方法 activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } if (!activity.mCalled) { thrownewSuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; mLastReportedWindowingMode.put(activity.getActivityToken(), config.windowConfiguration.getWindowingMode()); } r.setState(ON_CREATE);
// updatePendingActivityConfiguration() reads from mActivities to update // ActivityClientRecord which runs in a different thread. Protect modifications to // mActivities to avoid race. synchronized (mResourcesManager) { mActivities.put(r.token, r); }
@Override publicvoidhandleResumeActivity(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;
// **调用 Activity.onResume() 方法** // TODO Push resumeArgs into the activity for consideration finalActivityClientRecordr= 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; }
finalActivitya= r.activity;
if (localLOGV) { Slog.v(TAG, "Resume " + r + " started activity: " + a.mStartedActivity + ", hideForNow: " + r.hideForNow + ", finished: " + a.mFinished); }
// 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. booleanwillBeVisible= !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(); Viewdecor= r.window.getDecorView(); // 将 DecorView 设置为不可见 decor.setVisibility(View.INVISIBLE); ViewManagerwm= a.getWindowManager(); WindowManager.LayoutParamsl= r.window.getAttributes(); a.mDecor = 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. ViewRootImplimpl= decor.getViewRootImpl(); if (impl != null) { impl.notifyChildRebuilt(); } } // **通过 WindowManager 加载 DecorView** if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true; 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. } elseif (!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); ViewRootImplimpl= r.window.getDecorView().getViewRootImpl(); WindowManager.LayoutParamsl= 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) { ViewManagerwm= a.getWindowManager(); Viewdecor= r.window.getDecorView(); wm.updateViewLayout(decor, l); } }
/** * Sets the window token to assign when none is specified by the client or * available from the parent window. * * @param token The default token to assign. */ publicvoidsetDefaultToken(IBinder token) { mDefaultToken = token; }
privatevoidapplyDefaultToken(@NonNull ViewGroup.LayoutParams params) { // Only use the default token if we don't have a parent window. if (mDefaultToken != null && mParentWindow == null) { if (!(params instanceof WindowManager.LayoutParams)) { thrownewIllegalArgumentException("Params must be WindowManager.LayoutParams"); }
// Only use the default token if we don't already have a token. final WindowManager.LayoutParamswparams= (WindowManager.LayoutParams) params; if (wparams.token == null) { wparams.token = mDefaultToken; } } }
// do this last because it fires off messages to start doing things try { root.setView(view, wparams, panelParentView, userId); } catch (RuntimeException e) { // BadTokenException or InvalidDisplayException, clean up. if (index >= 0) { removeViewLocked(index, true); } throw e; } } } // 省略... }
voidcheckThread() { if (mThread != Thread.currentThread()) { thrownewCalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); } }
// Postpone the runnable until we know on which thread it needs to run. // Assume that the runnable will be successfully placed after attach. getRunQueue().post(action); returntrue; }