This is the 9th day of my participation in the August More Text Challenge

(1) The relationship between Activity,Window and View

View the rendering process from the Activity’s setContent method (2)

View the rendering process from the setContent method of the Activity (3) and then view the Window

See the rendering process from the setContent method of an AppCompatActivity

preface

In the first article, we learned about the view hierarchy of an App and analyzed how the XML we wrote was added to the Content. We learned about the relationship between the top-level view DecorView and PhoneWindow.

In the second article, introduces the Window addView, removeView, upDateViewLayout three important methods. View is drawn by ViewRootImpl and Window is displayed by WMA.

In this article, I’ll take another peek at Windows. The following constants are defined in the interface WindowManager

Different types of Windows

Windows has three categories.

Window The hierarchy
The application Window 1-99.
The child Window 1000 ~ 1999
The Window system 2000-2999.

Think of this classification we often see it. We know that the Activity uses the application Window, and then we write our own popover, is a child Window, child Winodw must rely on an application Window can be displayed, otherwise how to call the child Window, such as our popover, followed by the system Window, This is usually used at the system level, such as our toast, but we can also use it.

So let me show you in code how this is defined, 1 minus 99, 1000 minus 1999.

android.view.WindowManager @WindowType public int type; /** * Start of Window types that represent Normal Application Windows. */ public static final int FIRST_APPLICATION_WINDOW = 1; */ public static final int TYPE_APPLICATION = 2; public static final int TYPE_APPLICATION_STARTING = 3; public static final int TYPE_DRAWN_APPLICATION = 4; /** * End of types of application windows. */ public static final int LAST_APPLICATION_WINDOW = 99; Subwindow /** * Start of types of sub-windows. The {@link #token} of these Windows must be set to The Window they are  attached to. These types of * windows are kept next to their attached window in Z-order, and their * coordinate space is relative to their attached window. */ public static final int FIRST_SUB_WINDOW = 1000; . /** * End of types of sub-windows. */ public static final int LAST_SUB_WINDOW = 1999; System Window /** * Start of system-specific Window types. These are not normally * created by applications static final int FIRST_SYSTEM_WINDOW = 2000; /** * End of types of system windows. */ public static final int LAST_SYSTEM_WINDOW = 2999; .Copy the code

We see that there are five for the application Window, but not from 1 to 99. Of course, as long as I set the value between 1 and 99, the Window will be applied.

I don’t know if you’ve ever written about an app like a levitating ball, where you can and can follow your finger to update your position, but I first saw it on my iPhone. At first it might seem difficult, but it’s just a matter of passing in the coordinate system parameters as mentioned in the previous upDateViewLayout. If we want to define that the hover ball still exists when we switch to another App, we need to apply for the hover Window permission and set the hover ball Window to TYPE_SYSTEM_ALERT.

View analysis

Let’s do a simple Demo, pop up a popover, and see what the view hierarchy looks like.

Look at a screenshot of a cell phone

Take a look at the AS view analysis

In the interface of the Activity, I popped up a pop-up window and a toast, and then opened a third-party hover window APP. In view analysis, because the AS analysis tool can only analyze the current process, we only see 2 decorViews on the right, i.e. 2 PhoneWindows.

There are multiple Windows on the same screen, and the one that manages them is The WindowManagerService

Windows ManagerService, Windows ManagerGlobal, View rule PL

WindowManagerGlobal

We talked about wm.addView in attach. The final execution of the method is in Windows ManagerGlobal, with several variables inside.

Android. View. WindowManagerGlobal responsible and WMS communication private static IWindowSession sWindowSession; Private Final ArrayList<View> mViews = new ArrayList<View>(); ViewViewRootImpl Private Final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>(); All the View within the current application of the corresponding parameters of private final ArrayList < WindowManager. LayoutParams > mParams = new ArrayList<WindowManager.LayoutParams>(); private final ArraySet<View> mDyingViews = new ArraySet<View>();Copy the code

SWindowSession.

WindowManagerGlobal is itself a singleton, and sWindowSession is decorated static. It makes no sense that an Application has only one sWindowSession object.

As analyzed in the previous article, viewrotimPL uses sWindowSession to notify WMS of screen-specific display management.

But what exactly is this sWindowSession type?

@UnsupportedAppUsage public static IWindowSession getWindowSession() { synchronized (WindowManagerGlobal.class) { if (sWindowSession == null) { try { // Emulate the legacy behavior. The global instance of InputMethodManager // was instantiated here. // TODO(b/116157766): Remove this hack after cleaning up InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary(); IWindowManager windowManager = getWindowManagerService(); The key code sWindowSession = windowManager. OpenSession (new IWindowSessionCallback. Stub () {@ Override public void onAnimatorScaleChanged(float scale) { ValueAnimator.setDurationScale(scale); }}); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } return sWindowSession; }}Copy the code

We know that Windows Manager is really Windows Manager vice.

com.android.server.wm.WindowManageService @Override public IWindowSession openSession(IWindowSessionCallback callback) {  return new Session(this, callback); }Copy the code

SWindowSessionq was originally the Session class.

mViews,mRoots,mParams

MViews stores all views corresponding to Windows. This is the description I read in Android Development Art Quest, and I probably thought a little too much about it the first time I saw it.

  1. MViews stores the corresponding decorViews of all Windows
  2. MViews stores all views corresponding to all Windows

There’s a difference when you think about it. For example, in my simple Demo, one Actvity has a TextView and one ImgView. For the first, mViews are 1. For the second, mViews are not just 1. There are textViews, ImgView, FrameLayout with content, and so on.

MViews has two operations, add and remove.

Android. View. WindowManagerGlobal add public void addView (view view and ViewGroup. LayoutParams params, Display the Display, Window parentWindow, int userId) { ...... mViews.add(view); mRoots.add(root); mParams.add(wparams); . } remove void doRemoveView(ViewRootImpl root) {Boolean allViewsRemoved; synchronized (mLock) { final int index = mRoots.indexOf(root); if (index >= 0) { mRoots.remove(index); mParams.remove(index); final View view = mViews.remove(index); mDyingViews.remove(view); } allViewsRemoved = mRoots.isEmpty(); }}Copy the code

These two methods have been analyzed in the last article, but the focus is not on mViews,mRoots and mParams. Now let’s have a look at them again. The addition and operation of mViews,mRoots and mParams are always the same, that is, the length of the array is the same, one to one. For example, in mViews’ second DecorView, its layout parameters are stored in mParams’ second element, and its ViewRoot is stored in mRoots’ second element.

That is to say, Windows ManagerGlobal only manages Windows’ DecorView. How many layers are nested inside is its own business, and it doesn’t care. MViews stores the corresponding decorViews of all Windows. The DecorView in turn corresponds to a Window, so Windows ManagerGlobal manages the Window

mDyingViews

MDyingViews this is easy to understand, immediately there are some decorViews that will be deleted

A brief introduction to ViewRootImpl

In setView, the method starts, and it will requestLayout to refresh the layout

android.view.ViewRootImpl @Override public void requestLayout() { if (! mHandlingLayoutInLayoutRequest) { checkThread(); mLayoutRequested = true; scheduleTraversals(); } } void checkThread() { if (mThread ! = Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the original thread that created a view hierarchy can touch its views."); }}Copy the code

In the checkThread method, we see the familiar error: the UI cannot be updated on the child thread

ScheduleTraversals also provide a View rendering entry that triggers the View rendering process internally: Measure – > Layout – > draw. Then communicate with WMS internally through WindowSession to complete the rendering process of the interface.

The specific analysis of View View PL is not in the current series, after the View system analysis to do a detailed explanation.

Learn about Windows ManagerService

I don’t know if you get the feeling that there are a lot of places where it looks like you’re operating on a Window, but you’re actually operating on a View, or a DecorView under the Window. Because the Window is an abstract existence, what is actually displayed is its DecorView. So WMS manages which View is displayed at the top in the current state, so it actually manages the View, not the Window, but the View is in the Window. So it gives the impression that WMAS actually manages Windows. He’s just managing a DecorView that belongs to a Window

com.android.server.wm.WindowManagerService

 final ArraySet<Session> mSessions = new ArraySet<>();

Copy the code

WindowManagerService has a list of Sessions. SWindowSessionq is used by ViewRootImpl to communicate with WindowManagerService.

WMS internally maintains a collection of sessions and communicates with corresponding applications

Not to mention how WMS controls which views are displayed on the screen, or how you can’t get bogged down in code. The main reason is that I am only vaguely aware of it. Wait monkey years horse month I know, I will come out again.

WindowManagerService(WMS) and ActivityManagerService(AMS) are important parts of the Android FrameWork.

conclusion

  1. When initializing an Activity, the Attach method creates a PhoneWindow, binds it to the Activity, and binds the PhoneWindow and WindowManger. There are two binding operations.
  2. In setContent, we create a default DecorView for the PhoneWindow, and after a series of method calls, we select a layout that matches the Theme to the DecorView, and put our XML inside a FrameLayout with an ID of Content

Above is the view level initialization comb, below is the view rendering comb. Start with the handleResumeActivity method, wm.addView

  1. AddView is finally triggered by Windows ManagerGlobal
  2. WindowManagerGlobal is a singleton that contains a Session static variable that the current Application communicates with the WMS. It also contains a set of decorViews that correspond to all Windows in the current Application. Of course, also mRoots, mParams
  3. The ViewRooyImpal is responsible for drawing the View and communicating with the WMS through the Session
  4. WMS, like AMS, is a system service. WMS is mainly responsible for window management, and of course event distribution, which I didn’t mention in this article.