page7
In this article, we analyze the construction process of the W class. The W class is an inner class defined in the ViewRootImpl class. The definition of the W class is as follows:
static class W extends IWindow.Stub
It can be seen that W is essentially A Binder local object, in fact, this will be passed to WindowManagerService, WindowManagerService is to notify Activity object to perform some operations through
W. The constructor of W is as follows:
W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
mWindowSession = viewAncestor.mWindowSession;
} It can be
seen that W holds ViewRootImpl and WindowSession.
On page 8
, we analyze the implementation of the setView function of ViewRootImpl:
1 public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
2 synchronized (this) {
3 if (mView == null) {
4 mView = view;
5 mViewLayoutDirectionInitial = mView.getRawLayoutDirection();
6 mFallbackEventHandler.setView(view);
7 mWindowAttributes.copyFrom(attrs);
8 attrs = mWindowAttributes;
9 // Keep track of the actual window flags supplied by the client.
10 mClientWindowLayoutFlags = attrs.flags;
11
12 setAccessibilityFocus(null, null);
13
14 if (view instanceof RootViewSurfaceTaker) {
15 mSurfaceHolderCallback =
16 ((RootViewSurfaceTaker)view).willYouTakeTheSurface();
17 if (mSurfaceHolderCallback != null) {
18 mSurfaceHolder = new TakenSurfaceHolder();
19 mSurfaceHolder.setFormat(PixelFormat.UNKNOWN);
20 }
21 }
22
23 CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
24 mTranslator = compatibilityInfo.getTranslator();
25
26 // If the application owns the surface, don't enable hardware acceleration
27 if (mSurfaceHolder == null) {
28 enableHardwareAcceleration(mView.getContext(), attrs);
29 }
30
31 boolean restore = false;
32 if (mTranslator != null) {
33 mSurface.setCompatibilityTranslator(mTranslator);
34 restore = true;
35 attrs.backup();
36 mTranslator.translateWindowLayout(attrs);
37 }
38 if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
39
40 if (!compatibilityInfo.supportsScreen()) {
41 attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
42 mLastInCompatMode = true;
43 }
44
45 mSoftInputMode = attrs.softInputMode;
46 mWindowAttributesChanged = true;
47 mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED;
48 mAttachInfo.mRootView = view;
49 mAttachInfo.mScalingRequired = mTranslator! = Null;
50 mAttachInfo.mApplicationScale =
51 mTranslator == null? 1.0f: mTranslator.applicationScale;
52 if (panelParentView! = Null) {
53 mAttachInfo.mPanelParentWindowToken
54 = panelParentView.getApplicationWindowToken ();
55}
56 mAdded = true;
57 int res; /* = WindowManagerImpl.ADD_OKAY; */
58
59 // Schedule the first layout -before- adding to the window
60 // manager, to make sure we do the relayout before receiving
61 // any other events from the system.
62 requestLayout();
63 if ((mWindowAttributes.inputFeatures
64 & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
65 mInputChannel = new InputChannel();
66 }
67 try {
68 mOrigWindowType = mWindowAttributes.type;
69 mAttachInfo.mRecomputeGlobalAttributes = true;
70 collectViewAttributes ();
71 res = mWindowSession.addToDisplay (mWindow, mSeq, mWindowAttributes,
72 getHostVisibility (), mDisplay.getDisplayId (),
73 mAttachInfo.mContentInsets, mInputChannel);
74} catch (RemoteException e) {
75 mAdded = false;
76 mView = null;
77 mAttachInfo.mRootView = null;
78 mInputChannel = null;
79 mFallbackEventHandler.setView(null);
80 unscheduleTraversals();
81 setAccessibilityFocus(null, null);
82 throw new RuntimeException("Adding window failed", e);
83 } finally {
84 if (restore) {
85 attrs.restore();
86 }
87 }
88
89 if (mTranslator != null) {
90 mTranslator.translateRectInScreenToAppWindow(mAttachInfo.mContentInsets);
91 }
92 mPendingContentInsets.set(mAttachInfo.mContentInsets);
93 mPendingVisibleInsets.set(0, 0, 0, 0);
94 if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow);
95 if (res < WindowManagerGlobal.ADD_OKAY) {
96 mAttachInfo.mRootView = null;
97 mAdded = false;
98 mFallbackEventHandler.setView(null);
99 unscheduleTraversals();
100 setAccessibilityFocus(null, null);
101 switch (res) {
102 case WindowManagerGlobal.ADD_BAD_APP_TOKEN:
103 case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:
104 throw new WindowManager.BadTokenException(
105 "Unable to add window -- token " + attrs.token
106 + " is not valid; is your activity running?");
107 case WindowManagerGlobal.ADD_NOT_APP_TOKEN:
108 throw new WindowManager.BadTokenException(
109 "Unable to add window -- token " + attrs.token
110 + " is not for an application");
111 case WindowManagerGlobal.ADD_APP_EXITING:
112 throw new WindowManager.BadTokenException(
113 "Unable to add window -- app for token " + attrs.token
114 + " is exiting");
115 case WindowManagerGlobal.ADD_DUPLICATE_ADD:
116 throw new WindowManager.BadTokenException(
117 "Unable to add window -- window " + mWindow
118 + " has already been added");
119 case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:
120 // Silently ignore -- we would have just removed it
121 // right away, anyway.
122 return;
123 case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:
124 throw new WindowManager.BadTokenException(
125 "Unable to add window " + mWindow +
126 " -- another window of this type already exists");
127 case WindowManagerGlobal.ADD_PERMISSION_DENIED:
128 throw new WindowManager.BadTokenException(
129 "Unable to add window " + mWindow +
130 " -- permission denied for this window type");
131 case WindowManagerGlobal.ADD_INVALID_DISPLAY:
132 throw new WindowManager.InvalidDisplayException(
133 "Unable to add window " + mWindow +
134 " -- the specified display can not be found");
135 }
136 throw new RuntimeException(
137 "Unable to add window -- unknown error code " + res);
138 }
139
140 if (view instanceof RootViewSurfaceTaker) {
141 mInputQueueCallback =
142 ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
143 }
144 if (mInputChannel != null) {
145 if (mInputQueueCallback != null) {
146 mInputQueue = new InputQueue(mInputChannel);
147 mInputQueueCallback.onInputQueueCreated(mInputQueue);
148 } else {
149 mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
150 Looper.myLooper());
151 }
152 }
153
154 view.assignParent(this);
155 mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;
156 mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;
157
158 if (mAccessibilityManager.isEnabled()) {
159 mAccessibilityInteractionConnectionManager.ensureConnection();
160 }
161
162 if (view.getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
163 view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
164 }
165 }
166 }
167 }
168
Line 2 (ViewRootImpl->setView) will be locked
. Line 3 (ViewRootImpl->setView) will ensure that a ViewRootImpl corresponds to only one View
. Line 4 (ViewRootImpl->setView) sets the member variable mView to DecorView
62 The line (ViewRootImpl->setView) will call the requestLayout() function to perform a layout, and this is done before adding to the WindowManagerService management. For the analysis of this part, please refer to the analysis of the refresh part of the View.
Lines 71-73 ( ViewRootImpl->setView) will call the addToDisplay function of WindowSession to pass mWindow to WindowManagerService. For the analysis of this part, please refer to the article on the connection between Activity and WindowManagerService. On page 9 , let's take a look at the implementation of PhoneWidnow's getDecorView function:
public final View getDecorView() { if (mDecor == null) { installDecor(); } return mDecor; }
If the getDecorView function finds that mDecor has not been initialized, it will call the installDecor function to construct a DecorView
The creation process of Activity's ViewRoot (3)
Guess you like
Origin http://43.154.161.224:23101/article/api/json?id=326069977&siteId=291194637
Recommended
Ranking