The creation process of Activity's ViewRoot (3)

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326069977&siteId=291194637