Android Advanced: In-depth understanding of the Android window management framework mechanism

Android Advanced: In-depth understanding of the Android window management framework mechanism

[[423965]]

Preface

WindowManagerService is a window management service located in the Framework layer. Its responsibility is to manage all windows in the system, that is, Windows. In general, a Window is a display area on a mobile phone, that is, the drawing canvas Surface in Android. The process of adding a Window is the process of applying for a Surface, and the manager of the entire process is WindowManagerService.

Today we will analyze the knowledge points related to window WMS;

1. Window-related concepts

1. WindowManagerService concept

(1) WindowManagerService concept

The window management service of the Framework layer is responsible for managing all windows in the Android system. The window management service inherits IWindowManager.Stub and the Binder server, so the interaction between WM and WMS is also an IPC process. The main things that WMS does are as follows:

  • Z-ordered maintenance functions
  • Input method management
  • AddWindow/RemoveWindow
  • Layerout
  • Token management, AppToken
  • Active Window Management (FocusWindow)
  • Event App Management (FocusApp)
  • Transition Animation
  • System message collection thread
  • System message distribution thread

(2)WindowManager

The interface for applications to interact with the window management service WindowManagerService;

(3)PhoneWindowManager

Implemented various window strategies and defined window-related strategies, such as telling WMS what the Z-Order value of a certain type of Window is, helping WMS correct unreasonable window properties, monitoring the screen rotation status for WMS, and pre-processing some system key events;

(4)Choreographer

The user controls window animation, screen selection and other operations. It has the ability to obtain Vsync synchronization events from the display subsystem, so that it can notify the rendering action at the right time to avoid screen tearing caused by screen redrawing during the rendering process. WMS uses Choreographer to drive the rendering of all window animations, screen rotation animations, and wallpaper animations;

(5)DisplayContent

Used to describe information related to multi-screen output;

Group windows according to their display positions. Windows belonging to the same DisplayContent will be displayed on the same screen. Each DisplayContent corresponds to a unique ID. When adding a window, you can specify this ID to determine which screen it will be displayed on;

DisplayContent is a very isolated concept. Two windows in different DisplayContents will not have any coupling in layout, display order, and animation processing;

(6)WindowState

Describes the state information of the window and communicates with WindowManagerService. Generally, one window corresponds to one WindowState. It is used to represent all the properties of a window;

(7)WindowToken

  • Window Token, used for Binder communication; it is also an identifier;
  • When sorting windows in Zorder, windows belonging to the same WindowToken will be arranged together, and some properties defined in it will affect all windows belonging to this WindowToken, which shows the close connection between windows belonging to the same WindowToken;
  • When an application component needs a new window, it must provide a WindowToken to identify itself, and the type of the window must be consistent with the type of the WindowToken it holds;
  • When creating a system-type window, you do not need to provide a valid Token. WMS will implicitly declare a WindowToken for it. It seems that anyone can add a system-level window. Does Android ignore security for the convenience of internal use? No, the purpose of mPolicy.checkAddPermission() at the beginning of the addWindow() function is just that. It requires the client to have SYSTEM_ALERT_WINDOW or INTERNAL_SYSTEM_WINDOW permissions to create a system;

(8)Session

The App process establishes a connection with the WMS by establishing a Session proxy object to communicate with the Session object;

(9)SurfaceFlinger

SurfaceFlinger is responsible for managing the frame buffer of the Android system. The display screen of the Android device is abstracted as a frame buffer, and the SurfaceFlinger service in the Android system draws the user interface in the application by writing content to this frame buffer.

(10)InputManager

Manage the input event channel (InputChannel) of each window and dispatch events to the channel;

(11)Animator

The manager of all window animations (WindowStateAnimator object). Driven by Choreographer, all animations are rendered one by one;

2. Window

  • Represents the concept of a window, which is the direct manager of all Views. Any view is presented through Window (click events are handled by Window->DecorView->View; Activity's setContentView is handled by Window at the bottom layer)
  • Window is an abstract class, and its concrete implementation is PhoneWindow;
  • Creating a Window requires creating it through WindowManager;
  • WindowManager is the entrance for the outside world to access Window;
  • The specific implementation of Window is located in WindowManagerService;
  • The interaction between WindowManager and WindowManagerService is completed through IPC inter-process communication;
  • An abstract base class that defines window styles and behaviors, used to add a top-level View to WindowManager. Its implementation class is PhoneWindow.
  • Each Window needs to specify a Type (application window, child window, system window). The window corresponding to Activity is the application window; PhoneWindow, ContextMenu, and OptionMenu are commonly used child windows; Toast and system warning prompt boxes (such as ANR) are system windows, and many application floating windows are also system windows;

3. Surface

  • In Android, a window occupies a Surface exclusively. Surface is actually a canvas. Applications draw content on Surface through Canvas or OpenGL.
  • After drawing on the Surface, SurfaceFlinger mixes the contents of multiple Surfaces in Z-order and outputs them to FrameBuffer, thus displaying the Android page to the user;
  • Each window has a Surface to display its own UI, so a role is needed to manage the windows in a unified way. At this time, WMS came into being. WMS allocates Surface to all windows, manages the z-order, position, size, and entry and exit animation of windows, and is also a transfer station for input system;
  • Layout system: calculates and manages the position and hierarchy of windows;
  • Animation system: Renders window animations based on calculations by the layout system;

4. Window Type

  • Application window: The level range is 1~99
  • Subwindow: The level range is 1000~1999
  • System window: The level range is 2000~2999

5. Window flags display properties

  1. // Window feature flags
  2. public   int flags;
  3. // When the window is visible to the user, allow the screen to be locked
  4. public   static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001;
  5. // Darken everything behind the window
  6. public   static final int FLAG_DIM_BEHIND = 0x00000002;
  7. // Everything behind the window is blurred
  8. public   static final int FLAG_BLUR_BEHIND = 0x00000004;
  9. // The window cannot get focus
  10. public   static final int FLAG_NOT_FOCUSABLE = 0x00000008;
  11. // The window does not accept touch screen events
  12. public   static final int FLAG_NOT_TOUCHABLE = 0x00000010;
  13. //Allow click events from this window to be passed to the window behind the current window, even if the window can get focus
  14. public   static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;
  15. // When the phone is in sleep mode, if the screen is pressed, this window will be the first to receive the touch event
  16. public   static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;
  17. // When the window is visible to the user, the screen is always on
  18. public   static final int FLAG_KEEP_SCREEN_ON = 0x00000080;
  19. // Make the window fill the entire screen without leaving any borders
  20. public   static final int FLAG_LAYOUT_IN_SCREEN = 0x00000100;
  21. // Allow the window to exceed the entire phone screen
  22. public   static final int FLAG_LAYOUT_NO_LIMITS = 0x00000200;
  23. //Window full name display
  24. public   static final int FLAG_FULLSCREEN = 0x00000400;
  25. // Restore window non-full screen display
  26. public   static final int FLAG_FORCE_NOT_FULLSCREEN = 0x00000800;
  27. // Enable window jitter
  28. public   static final int FLAG_DITHER = 0x00001000;
  29. //Secure content window. Screen capture is not allowed when this window is displayed.
  30. public   static final int FLAG_SECURE = 0x00002000;
  31. // A special mode in which layout parameters are used to perform scaling when compositing the surface to the screen.
  32. public   static final int FLAG_SCALED = 0x00004000;
  33. public   static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;
  34. public   static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
  35. public   static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
  36. // Receive a single special MotionEvent for touches occurring outside the window.
  37. // Instead of receiving the full down/up/up gesture, only the position of the first down gesture will be received as ACTION_OUTSIDE.
  38. public   static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
  39. // Display this window when the screen is locked
  40. public   static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
  41. // The system's wallpaper is displayed behind this window
  42. public   static final int FLAG_SHOW_WALLPAPER = 0x00100000;
  43. // When the window is displayed, the system will treat it as a user activity event to light up the phone screen
  44. public   static final int FLAG_TURN_SCREEN_ON = 0x00200000;
  45. // This window is displayed and the keyboard disappears
  46. public   static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
  47. // When the window can accept the touch screen, let the signal be sent to the window behind because it is outside the window
  48. // The touch screen can support split touch
  49. public   static final int FLAG_SPLIT_TOUCH = 0x00800000;
  50. // Hardware acceleration for this window. This flag must be set before the content view of the activity or dialog.
  51. public   static final int FLAG_HARDWARE_ACCELERATED = 0x01000000;
  52. // Let the window fill the entire phone screen without leaving any borders
  53. public   static final int FLAG_LAYOUT_IN_OVERSCAN = 0x02000000;
  54. // Transparent status bar
  55. public   static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;
  56. // Transparent navigation bar
  57. public   static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;

2. Window Adding Process

  1. public final class WindowManagerGlobal {
  2. public void addView( View   view , ViewGroup.LayoutParams params,
  3. Display display, Window parentWindow) {
  4. //Check the validity of the parameters
  5. ...
  6. //ViewRootImpl encapsulates the interaction between View and WindowManager
  7. ViewRootImpl root;
  8. View panelParentView = null ;
  9. synchronized (mLock) {
  10. // Start watching for system property changes.
  11. if (mSystemPropertyUpdater == null ) {
  12. mSystemPropertyUpdater = new Runnable() {
  13. @Override public void run() {
  14. synchronized (mLock) {
  15. for ( int i = mRoots. size () - 1; i >= 0; --i) {  
  16. mRoots.get(i).loadSystemProperties();
  17. }
  18. }
  19. }
  20. };
  21. SystemProperties.addChangeCallback(mSystemPropertyUpdater);
  22. }
  23. int   index = findViewLocked( view , false );
  24. if ( index >= 0) {
  25. if (mDyingViews. contains ( view )) {
  26. // Don 't wait for MSG_DIE to make it's way through root's queue.
  27. mRoots.get( index ).doDie();
  28. } else {
  29. throw new IllegalStateException( "View " + view  
  30. + " has already been added to the window manager." );
  31. }
  32. // The previous removeView() had not completed executing. Now it has.
  33. }
  34. // If this is a panel window, then find the window it is being
  35. // attached to   for future reference.
  36. if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
  37. wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
  38. final int   count = mViews.size () ;
  39. for ( int i = 0; i < count ; i++) {
  40. if (mRoots.get(i).mWindow.asBinder() == wparams.token) {
  41. panelParentView = mViews.get(i);
  42. }
  43. }
  44. }
  45. //Build ViewRootImpl through context
  46. root = new ViewRootImpl( view .getContext(), display);
  47. view .setLayoutParams(wparams);
  48. //mViews stores all View objects corresponding to Window
  49. mViews.add ( view );
  50. //mRoots stores the ViewRootImpl objects corresponding to all Windows
  51. mRoots.add (root);
  52. //mParams stores the WindowManager.LayoutParams objects corresponding to all Windows
  53. mParams.add (wparams);
  54. }
  55. // do this last because it fires off messages to start doing things
  56. try {
  57. //Call ViewRootImpl.setView() method to complete the addition of Window and update the interface
  58. root.setView( view , wparams, panelParentView);
  59. } catch (RuntimeException e) {
  60. // BadTokenException or InvalidDisplayException, clean up.
  61. synchronized (mLock) {
  62. final int   index = findViewLocked( view , false );
  63. if ( index >= 0) {
  64. removeViewLocked( index , true );
  65. }
  66. }
  67. throw e;
  68. }
  69. }
  70. }

There are three important member variables in this method:

  • mViews stores all View objects corresponding to Windows;
  • mRoots stores the ViewRootImpl objects corresponding to all Windows;
  • mParams stores the WindowManager.LayoutParams objects corresponding to all Windows;
  • Here we mention a class ViewRootImpl that we are not very familiar with. It is actually an encapsulation class that encapsulates the interaction between View and WindowManager. It is a bridge for communication between View and WindowManagerService.
  • Finally, the ViewRootImpl.setView() method is called to complete the addition of Window and update the interface;

Let's look at the implementation of this method

  1. public final class ViewRootImpl implements ViewParent,
  2. View .AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {
  3. public void setView( View   view , WindowManager.LayoutParams attrs, View panelParentView) {
  4. synchronized (this) {
  5. if (mView == null ) {
  6. mView = view ;
  7. //Parameter verification and preprocessing
  8. ...
  9. // Schedule the first layout -before- adding to the window
  10. // manager, to make sure we do the relayout before receiving
  11. // any other events from the system.
  12. //1. Call requestLayout() to complete the request for asynchronous drawing of the interface
  13. requestLayout();
  14. if ((mWindowAttributes.inputFeatures
  15. & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
  16. mInputChannel = new InputChannel();
  17. }
  18. mForceDecorViewVisibility = (mWindowAttributes.privateFlags
  19. & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
  20. try {
  21. mOrigWindowType = mWindowAttributes.type;
  22. mAttachInfo.mRecomputeGlobalAttributes = true ;
  23. collectViewAttributes();
  24. //2. Create WindowSession and request WindowManagerService through WindowSession to complete the process of adding Window
  25. //This is an IPC process.
  26. res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
  27. getHostVisibility(), mDisplay.getDisplayId(),
  28. mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
  29. mAttachInfo.mOutsets, mInputChannel);
  30. } catch (RemoteException e) {
  31. mAdded = false ;
  32. mView = null ;
  33. mAttachInfo.mRootView = null ;
  34. mInputChannel = null ;
  35. mFallbackEventHandler.setView( null );
  36. unscheduleTraversals();
  37. setAccessibilityFocus( null , null );
  38. throw new RuntimeException( "Adding window failed" , e);
  39. } finally {
  40. if (restore) {
  41. attrs.restore();
  42. }
  43. }
  44. ...
  45. }
  46. }
  47. }
  • Call requestLayout() to complete the request for asynchronous drawing of the interface. requestLayout() will call scheduleTraversals() to complete the drawing of the View. The scheduleTraversals() method submits a TraversalRunnable to the work queue to execute the drawing of the View. The TraversalRunnable finally calls the performTraversals() method to complete the actual drawing operation. We are already familiar with the performTraversals() method;
  • Create WindowSession and request WindowManagerService through WindowSession to complete the process of adding Window. This is an IPC process. WindowManagerService is the actual window manager. It is responsible for the creation, deletion and update of windows. It is also responsible for the stacking sorting and size calculation of windows.

Implementation of performTraversals() method:

  • Get the Surface object for graphics drawing;
  • Call the performMeasure() method to measure the size of each View in the view tree;
  • Call the performLayout() method to calculate the position of each View in the view tree and perform layout;
  • Call the performMeasure() method to draw each View in the view tree;

Cross-process communication between WindowManager and WindowManagerService. All services in Android are designed based on the C/S structure. The system layer provides services and the application layer uses services. The same is true for WindowManager.

The communication of WindowManagerService is done through WindowSession;

First, call ServiceManager.getService("window") to get WindowManagerService. This method returns an IBinder object. Then call IWindowManager.Stub.asInterface() to convert WindowManagerService into an IWindowManager object.

Then call the openSession() method to establish a communication session with WindowManagerService to facilitate subsequent cross-process communication. This communication session is the WindowSession we will use later;

Basically all Android system services are implemented in this way, which is an IPC process based on AIDL;

  1. public final class WindowManagerGlobal {
  2. public   static IWindowSession getWindowSession() {
  3. synchronized (WindowManagerGlobal.class) {
  4. if (sWindowSession == null ) {
  5. try {
  6. InputMethodManager imm = InputMethodManager.getInstance();
  7. //Get the WindowManagerService object and convert it to IWindowManager type
  8. IWindowManager windowManager = getWindowManagerService();
  9. //Call the openSession() method to establish a communication session with WindowManagerService to facilitate subsequent
  10. //Cross-process communication.
  11. sWindowSession = windowManager.openSession(
  12. new IWindowSessionCallback.Stub() {
  13. @Override
  14. public void onAnimatorScaleChanged( float scale) {
  15. ValueAnimator.setDurationScale(scale);
  16. }
  17. },
  18. imm.getClient(), imm.getInputContext());
  19. } catch (RemoteException e) {
  20. throw e.rethrowFromSystemServer();
  21. }
  22. }
  23. return sWindowSession;
  24. }
  25. }
  26. public   static IWindowManager getWindowManagerService() {
  27. synchronized (WindowManagerGlobal.class) {
  28. if (sWindowManagerService == null ) {
  29. //Call ServiceManager.getService( "window" ) to get WindowManagerService. This method returns an IBinder object.
  30. //Then call the IWindowManager.Stub.asInterface() method to convert the WindowManagerService to an IWindowManager object
  31. sWindowManagerService = IWindowManager.Stub.asInterface(
  32. ServiceManager.getService( "window" ));
  33. try {
  34. if (sWindowManagerService != null ) {
  35. ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
  36. }
  37. } catch (RemoteException e) {
  38. throw e.rethrowFromSystemServer();
  39. }
  40. }
  41. return sWindowManagerService;
  42. }
  43. }
  44. }

3. Window deletion process

The Window deletion process is also completed in WindowManagerGlobal

  1. public final class WindowManagerGlobal {
  2. public void removeView( View   view , boolean immediate) {
  3. if ( view == null ) {
  4. throw new IllegalArgumentException( "view must not be null" );
  5. }
  6. synchronized (mLock) {
  7. //1. Find the index of the View to be deleted
  8. int   index = findViewLocked( view , true );
  9. View curView = mRoots.get( index ).getView();
  10. //2. Call removeViewLocked() to complete the deletion of View , removeViewLocked() method
  11. //Continue to call ViewRootImpl.die() method to complete the deletion of View .
  12. removeViewLocked( index , immediate);
  13. if (curView == view ) {
  14. return ;
  15. }
  16. throw new IllegalStateException( "Calling with view " + view  
  17. + " but the ViewAncestor is attached to " + curView);
  18. }
  19. }
  20. private void removeViewLocked( int   index , boolean immediate) {
  21. ViewRootImpl root = mRoots.get( index );
  22. View   view = root.getView();
  23. if ( view != null ) {
  24. InputMethodManager imm = InputMethodManager.getInstance();
  25. if (imm != null ) {
  26. imm.windowDismissed(mViews.get( index ).getWindowToken());
  27. }
  28. }
  29. boolean deferred = root.die(immediate);
  30. if ( view != null ) {
  31. view .assignParent( null );
  32. if (deferred) {
  33. mDyingViews.add ( view );
  34. }
  35. }
  36. }
  37. }

Let's take a look at the implementation of the ViewRootImpl.die() method;

  1. public final class ViewRootImpl implements ViewParent,
  2. View .AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {
  3. boolean die(boolean immediate) {
  4. // Make sure we do execute immediately if we are in the middle of a traversal or the damage
  5. // done by dispatchDetachedFromWindow will cause havoc on   return .
  6. //Determine whether to perform asynchronous or synchronous deletion based on the immediate parameter
  7. if (immediate && !mIsInTraversal) {
  8. doDie();
  9. return   false ;
  10. }
  11. if (!mIsDrawing) {
  12. destroyHardwareRenderer();
  13. } else {
  14. Log.e(mTag, "Attempting to destroy the window while drawing!\n" +
  15. " window=" + this + ", title=" + mWindowAttributes.getTitle());
  16. }
  17. //If it is asynchronous deletion, sending a message MSG_DIE to delete the View will return directly
  18. mHandler.sendEmptyMessage(MSG_DIE);
  19. return   true ;
  20. }
  21. void doDie() {
  22. checkThread();
  23. if (LOCAL_LOGV) Log.v(mTag, "DIE in " + this + " of " + mSurface);
  24. synchronized (this) {
  25. if (mRemoved) {
  26. return ;
  27. }
  28. mRemoved = true ;
  29. if (mAdded) {
  30. //Call dispatchDetachedFromWindow() to complete the deletion of View
  31. dispatchDetachedFromWindow();
  32. }
  33. if (mAdded && !mFirst) {
  34. destroyHardwareRenderer();
  35. if (mView != null ) {
  36. int viewVisibility = mView.getVisibility();
  37. boolean viewVisibilityChanged = mViewVisibility != viewVisibility;
  38. if (mWindowAttributesChanged || viewVisibilityChanged) {
  39. // If layout params have been changed, first give them
  40. // to the window manager to make sure it has the correct
  41. // animation info.
  42. try {
  43. if ((relayoutWindow(mWindowAttributes, viewVisibility, false )
  44. & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
  45. mWindowSession.finishDrawing(mWindow);
  46. }
  47. } catch (RemoteException e) {
  48. }
  49. }
  50. mSurface.release();
  51. }
  52. }
  53. mAdded = false ;
  54. }
  55. //Refresh the data and remove the related information of the currently removed View from the three lists we mentioned above: mRoots, mParms and mViews.
  56. WindowManagerGlobal.getInstance().doRemoveView(this);
  57. }
  58. void dispatchDetachedFromWindow() {
  59. //1. Call back the View 's dispatchDetachedFromWindow method to notify that the View has been removed from the Window
  60. if (mView != null && mView.mAttachInfo != null ) {
  61. mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange( false );
  62. mView.dispatchDetachedFromWindow();
  63. }
  64. mAccessibilityInteractionConnectionManager.ensureNoConnection();
  65. mAccessibilityManager.removeAccessibilityStateChangeListener(
  66. mAccessibilityInteractionConnectionManager);
  67. mAccessibilityManager.removeHighTextContrastStateChangeListener(
  68. mHighContrastTextManager);
  69. removeSendWindowContentChangedCallback();
  70. destroyHardwareRenderer();
  71. setAccessibilityFocus( null , null );
  72. mView.assignParent( null );
  73. mView = null ;
  74. mAttachInfo.mRootView = null ;
  75. mSurface.release();
  76. if (mInputQueueCallback != null && mInputQueue != null ) {
  77. mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
  78. mInputQueue.dispose();
  79. mInputQueueCallback = null ;
  80. mInputQueue = null ;
  81. }
  82. if (mInputEventReceiver != null ) {
  83. mInputEventReceiver.dispose();
  84. mInputEventReceiver = null ;
  85. }
  86. //Call WindowSession.remove() method, which is also an IPC process, and finally calls
  87. //WindowManagerService.removeWindow() method to remove Window.
  88. try {
  89. mWindowSession.remove(mWindow);
  90. } catch (RemoteException e) {
  91. }
  92. // Dispose the input channel after removing the window so the Window Manager
  93. // doesn't interpret the input channel being closed as an abnormal termination.
  94. if (mInputChannel != null ) {
  95. mInputChannel.dispose();
  96. mInputChannel = null ;
  97. }
  98. mDisplayManager.unregisterDisplayListener(mDisplayListener);
  99. unscheduleTraversals();
  100. }
  101. }

Window deletion process:

  • Find the index of the View to be deleted (mViews.indexOf(view));
  • Call removeViewLocked() to complete the deletion of View, and continue to call the removeViewLocked() method; ViewRootImpl.die() method to complete the deletion of View;
  • The ViewRootImpl.die() method determines whether to perform asynchronous or synchronous deletion based on the immediate parameter. If it is asynchronous deletion, it will send a message MSG_DIE to delete the View and return directly. If it is synchronous deletion, it will call the doDie() method;
  • The doDie() method calls dispatchDetachedFromWindow() to complete the deletion of View. In this method, the dispatchDetachedFromWindow method of View is first called back to notify that the View has been removed from the Window, and then the WindowSession.remove() method is called. This is also an IPC process. Finally, the WindowManagerService.removeWindow() method is called to remove the Window.

4. Window update process

  1. public final class WindowManagerGlobal {
  2. public void updateViewLayout( View   view , ViewGroup.LayoutParams params) {
  3. if ( view == null ) {
  4. throw new IllegalArgumentException( "view must not be null" );
  5. }
  6. if (!(params instanceof WindowManager.LayoutParams)) {
  7. throw new IllegalArgumentException( "Params must be WindowManager.LayoutParams" );
  8. }
  9. final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
  10. //Update the View 's LayoutParams parameters
  11. view .setLayoutParams(wparams);
  12. synchronized (mLock) {
  13. //Find the index of Viewd and update the parameters in mParams
  14. int   index = findViewLocked( view , true );
  15. ViewRootImpl root = mRoots.get( index );
  16. mParams.remove( index );
  17. mParams.add ( index , wparams);
  18. //Call ViewRootImpl.setLayoutParams() to complete the layout.
  19. root.setLayoutParams(wparams, false );
  20. }
  21. }
  22. }
  23. Let's take a look at the implementation of the ViewRootImpl.setLayoutParams() method.
  24. public final class ViewRootImpl implements ViewParent,
  25. void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
  26. synchronized (this) {
  27. //Parameter preprocessing
  28. ...
  29. //If it is a new View , call requestLayout() to redraw
  30. if (newView) {
  31. mSoftInputMode = attrs.softInputMode;
  32. requestLayout();
  33. }
  34. // Don't lose the mode we last auto-computed.
  35. if ((attrs.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
  36. == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED) {
  37. mWindowAttributes.softInputMode = (mWindowAttributes.softInputMode
  38. & ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
  39. | (oldSoftInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST);
  40. }
  41. mWindowAttributesChanged = true ;
  42. //If it is not a new View , call requestLayout() to redraw
  43. scheduleTraversals();
  44. }
  45. }
  46. }

Window update process:

  • Update the LayoutParams parameters of View, find the index of View, and update the parameters in mParams;
  • Call ViewRootImpl.setLayoutParams() method to complete the re-layout work, and scheduleTraversals() will be called in the setLayoutParams() method;
  • Decode and redraw, the subsequent process of scheduleTraversals() is the measure, layout and draw process of View;

Summarize

What is the essence of Window? In fact, Window is an abstract concept, that is, it does not actually exist, it exists in the form of View, each Window corresponds to a View and a ViewRootImpl, and Window and View are connected through ViewRootImpl. By extension, we can understand that WindowManagerService actually manages View rather than Window, which manages which View should be displayed on the top layer in the current state, and SurfaceFlinger drawing is also View;

<<:  Official release is imminent, Apple: App Store now open for iOS 15 and iPadOS 15 app submissions

>>:  Master three steps to create a collaborative component library from scratch

Recommend

SEO trends in 2019: How to do SEO in 2019?

SEO trends in 2019: How to do SEO in 2019? I was ...

Apple has fixed the bug that caused iPhones to crash instantly

[[135484]] Earlier this week, iPhone users discov...

Is Android controlled by Google not a good Android?

[[130355]] Mitch Lasky, partner at Silicon Valley...

Tablets have no future: iPad replacing PC is a false proposition

Did you notice this detail at the Apple new produ...

How does product operations carry out product planning?

Recently I have been exploring a new business tha...

Year-end review: This year, we pursued our dreams and settled in space

◎ Science and Technology Daily reporter Jin Feng ...

Do dogs also have their periods? What should you do when they do?

A few days ago, a dog owner found that his dog ha...

Is it the season for rashes again? Don’t worry, take a look at Feng Shui first

My child has a high fever and a rash? Rubella, me...