Detailed explanation of Android window management mechanism

 Android system startup

1, "Introduction to the Android System Startup Process"

2, "Android init process startup process"

3. "Android zygote process startup process"

4. "Android SystemServer Process Startup Process"

5. "Android launcher startup process"

6. "Detailed Explanation of Android Activity Startup Process"

Android System Development Preparation

1, "Android Source Code Download and Compilation"

2. "Android 11 source code compilation and pixel3 flashing"

3. "Android Framework Code IDE Loading and Debugging"

Android System Development Practice

1. "Android Setting Default Input Method"

2, "android framework prefabricated APK application"

3. "Detailed Explanation of Restricting Apps from Starting at the Android System Level"

4. "Android compiles the framework module separately and pushes it"

5. "Android Framework Development System Problem Analysis"

Android System Development Core Knowledge Reserve

1, "Android Compilation System - envsetup and lunch code articles"

2. "Android Compilation System - Concept"

3. "Detailed Explanation of Android Log System"

4. "Android System Handler Detailed Explanation"

5. "Android System Binder Detailed Explanation"

6. "Detailed Explanation of the Relationship between Activity, View and Window in Android"

7. "Detailed Explanation of the Android View Drawing Process"

8. "Detailed Explanation of Android Reading System Attributes"

9. "Detailed Explanation of Android Window Management Mechanism"

10. "Acquaintance with Android System"

11. "The communication method of AMS process in android notifying Zygote process fork new process"

Detailed explanation of Android core functions

1. "Android application market click to download APK installation details"

2, "Android gesture navigation (swipe from bottom to top to enter the multitasking page)"

3. "Android Gesture Analysis (Swipe left to right on the application interface to exit the application)"

4. "Detailed Explanation of Android Application Installation Process"

5, "android11 ​​installation application triggers desktop icon refresh process"

6. "Detailed Explanation of Android System Multitasking Recents"

7. "Android System Navigation Bar View Analysis"

———————————————————————————————————————————

Table of contents

1. Basic introduction

2. Window

Three, WindowManager

四、WindowManagerService

Five, summary

1. Basic introduction

        Android window management is mainly implemented by Window, WindowManager, and WindowManagerService. Window represents an abstract set of functions, which is implemented as PhoneWindow. WindowManager is the entrance for the outside world to access Window. The access to Window must pass through WindowManager, and the interaction between WindowManger and WindowManagerService is a cross-process communication process. All views in Android are presented through Window, whether it is Activity, Dialog, Toast, their views are attached to Window. The relationship is as shown in the figure below,

2. Window

        FrameWork defines three window types, and the three types are defined in WindowManager.

1. The application window corresponds to an Activity. Loading the Activity is done by AmS, and creating an application window can only be done inside the Activity.

2. Child windows must be attached to any type of parent window.

3. The system window does not need to correspond to any Activity, and the application cannot create a system window.

        WindowManager refines these three types, marking each type with an int constant. When WmS overlays windows, it will allocate different layers according to the size of the int constant. The larger the int value, the higher the position of the layer. Here The int value is called the level.

        Each Window has a corresponding z-ordered, and the higher-level windows will cover the smaller-level windows, which is completely consistent with the z-index concept in HTML. Among the three types of windows, the application window level range is 1~99, the sub-window level range is 1000~1999, and the system window level range is 2000~2999. These level ranges correspond to the type parameter of WindowManager.LayoutParams. If you want the Window to be located in The topmost layer of all windows, then use a larger layer, obviously the layer of the system window is the largest. The corresponding relationship between each window type and TYPE is as follows,

Write picture description here

Write picture description here

Write picture description here         

        Window is an abstract concept. Each Window corresponds to a View and a ViewRootImpl. Window and View are connected through ViewRootImpl. As shown below:

Three, WindowManager

        WindowManager is the hub of the entire window management mechanism, and it is also the focus here. WindowManager implements ViewManager, which defines our basic operations on Window:


public interface ViewManager

{

    public void addView(View view, ViewGroup.LayoutParams params);

    public void updateViewLayout(View view, ViewGroup.LayoutParams params);

    public void removeView(View view);

}

        These three methods are actually the main functions provided by WindowManager, namely adding View, updating View and deleting View. See an example of adding Window through WindowManager:


public class MainActivity extends AppCompatActivity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Button floatingButton = new Button(MainActivity.this);

        floatingButton.setText("button");

        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(

                WindowManager.LayoutParams.WRAP_CONTENT,

                WindowManager.LayoutParams.WRAP_CONTENT,

                0, 0,

                PixelFormat.TRANSPARENT

        );

        // flag 设置 Window 属性

        layoutParams.flags= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

        // type 设置 Window 类别(层级)

        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

        layoutParams.gravity = Gravity.CENTER;

        WindowManager windowManager = getWindowManager();

        windowManager.addView(floatingButton, layoutParams);

    }

}

The effect is as follows,

        During the startup process of the Activity, the ActivityThread will call the performLaunchActivity() function, which will call the OnCreate() method of the Activity through layers of depth, and the attach() of the Activity will be called before the OnCreate() method is called in performLaunchActivity() method,


// ActivityThread.class

final void attach(Context context, ActivityThread aThread,

            Instrumentation instr, IBinder token, int ident,

            Application application, Intent intent, ActivityInfo info,

            CharSequence title, Activity parent, String id,

            NonConfigurationInstances lastNonConfigurationInstances,

            Configuration config, String referrer, IVoiceInteractor voiceInteractor,

            Window window, ActivityConfigCallback activityConfigCallback) {

        ...

        // 创建PhoneWindow并设置其回调接口

        mWindow = new PhoneWindow(this, window, activityConfigCallback);

        mWindow.setWindowControllerCallback(this);

        mWindow.setCallback(this);

        mWindow.setOnWindowDismissedCallback(this);

        mWindow.getLayoutInflater().setPrivateFactory(this);

        ...

        // 将该Window和WindowManager绑定

        mWindow.setWindowManager(

                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),

                mToken, mComponent.flattenToString(),

                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

    ...

        // 设置管理Activity的Window的WindowManager

        mWindowManager = mWindow.getWindowManager();

    ...

    }

In the attach() method, the Window of the Activity is created, and the WindowManager is bound to the Window at the same time, and the WindowManager is passed to the member variable mWindowManager of the Activity. At the same time, we can see that the concrete implementation class of Window is PhoneWindow.

Go into the setWindowManager() method and take a look:


public void setWindowManager(WindowManager wm, IBinder appToken, String appName,

            boolean hardwareAccelerated) {

    ...

        if (wm == null) {

            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);

        }

        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);

    }

        This method mainly creates the Window object of the Activity, and obtains the WindowManager that manages the Window. At this time, the View corresponding to the Activity is not actually attached to this Window. And the code to attach this View to Window is actually the setContentView(int layoutResID) we often call in OnCreate():


// Activity.class

public void setContentView(int layoutResID){

  getWindow().setContentView(layoutResID);

   ...

}

        The method call finally calls setContentView(layoutResID) of getWindow(), and what getWindow() gets is the PhoneWindow created in attach(). Let's go in and take a look:


// PhoneWindow.class

 @Override
    public void setContentView(int layoutResID) {
        if (mContentParent == null) {
            installDecor();
        } else {
            mContentParent.removeAllViews();
        }
        mLayoutInflater.inflate(layoutResID, mContentParent);
        final Callback cb = getCallback();
        if (cb != null && !isDestroyed()) {
            cb.onContentChanged();
        }
    }

        Call setContentView to bind the window to the View. As you can see, first determine whether mContentParent is null, if so, call installDecor(), otherwise remove all the child Views inside it, and then place the layout we passed in into mContentParent through LayoutInflater.inflate.

        After the Activity calls the onResume method, it will call the makeVisible() method to add the window to the windowManager, so that the windowManager can manage the window.


void makeVisible() {

        if (!mWindowAdded) {

            ViewManager wm = getWindowManager();

            wm.addView(mDecor, getWindow().getAttributes());

            mWindowAdded = true;

        }

        mDecor.setVisibility(View.VISIBLE);

    }

        The window is abstract and must be accessed through the windowManager. The windowManager is inherited from the viewmanager, and it provides operations for adding, deleting, and modifying views. The view is bound to the window, so the operation on the View is actually the operation on the window.
        As can be seen from the above code, the specific implementation class of windowManager is actually WindowManagerImpl,


@Override

        public void addView(View view, ViewGroup.LayoutParams params){

        ...

            mGlobal.addView(view, params, mDisplay, mParentWindow);

        }

        @Override

        public void updateViewLayout(View view, ViewGroup.LayoutParams params){

        ...

            mGlobal.updateViewLayout(view, params);

        }

        @Override

        public void removeView(View view){

        ...

            mGlobal.removeView(view, false);

        }


It hands over the operation of the view to the member mGlobal. mGlobal is a WindowManagerGlobal class. Let’s take a look at its source code. mGlobal provides the operation functions for adding, deleting, and modifying the view. At the same time, it also uses several The collection is used to save the information related to the window, as follows.

public final class WindowManagerGlobal{
	// 存储所有window对应的View
    private final ArrayList<View> mViews = new ArrayList<View>();
	// 存储所有window对应的ViewRootImpl
    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
    // 存储所有的window对应的布局参数 
    private final ArrayList<WindowManager.LayoutParams> mParams =new ArrayList<WindowManager.LayoutParams>();
     //  存储已经调用removeView方法但是操作删除还未完成的对象
    private final ArraySet<View> mDyingViews = new ArraySet<View>();

	public void addView(...){
		...
	}
	public void updateViewLayout(...){
		...
	}
	public void removeView(...){
		...
	}
	...
}

        The call path from WindowManager to WindowManagerService is

四、WindowManagerService

        The addWindow() method has been called through the proxy of WindowManagerService above, which is very complicated. The main operation is to save the passed Window according to its parameters, especially its type. Facilitate SurfaceFlinger rendering.

     In the file IWindowManager.aidl, we can see what functions WindowManagerService can provide

......
    void getBaseDisplaySize(int displayId, out Point size);
    void setForcedDisplaySize(int displayId, int width, int height);
    void clearForcedDisplaySize(int displayId);
    @UnsupportedAppUsage
    int getInitialDisplayDensity(int displayId);
    int getBaseDisplayDensity(int displayId);
    void setForcedDisplayDensityForUser(int displayId, int density, int userId);
    void clearForcedDisplayDensityForUser(int displayId, int userId);
    void setForcedDisplayScalingMode(int displayId, int mode); // 0 = auto, 1 = disable

    void setOverscan(int displayId, int left, int top, int right, int bottom);

    // These can only be called when holding the MANAGE_APP_TOKENS permission.
    void setEventDispatching(boolean enabled);
    void addWindowToken(IBinder token, int type, int displayId);
    void removeWindowToken(IBinder token, int displayId);
    void setFocusedApp(IBinder token, boolean moveFocusNow);
    void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
    ......

        It can be seen from the interface definition that WMS has many functions, such as obtaining display information, capturing screen, locking screen and other functions.

Five, summary

        The android window management process is roughly as follows:

1. Create a Window and bind the View and ViewRootImpl to the Window.

2. WindowManager's addView(), updateViewLayout() and removeView() methods operate Window.

3. Transfer the operation methods of WindowManager to WindowManagerGobal to call.

4. Call the setView() method of ViewRootImpl bound to Window.

5. In the setView() method, the Window will be passed to the WindowManagerService through the Binder object mWindowSession.

6, WindowManagerService to manage the size and display position of each Window, to allow SurfaceFlinger to render.

Guess you like

Origin blog.csdn.net/allen_xu_2012_new/article/details/130777822