1. Understand Android's Window
Window represents the concept of a window, an abstract concept. Each Window corresponds to a View and a ViewRootImpl. Window and View are connected through ViewRootImpl. Therefore, Window does not actually exist, it exists in the form of a View.
Each window view in Android has a corresponding Window, such as Activity and Dialog. When they are initialized, they will create the corresponding PhoneWindow and assign it to a reference inside it.
The level of window
set up
Each window has its corresponding level. If the application window is at 1-99, the sub-window is at 1000-1999, the system window is at 2000-2999, the higher level will cover the lower level
The child window must depend on the parent window. For example, Dialog must pop up in the Activity, the window in Dialog is the child window, and the window in Activity is the parent window
Displaying system-level window requires permissions<uses-permission android:name=".SYSTEM_ALERT_WINDOW" />
WindowLayoutparams flags
FLAG_NOT_FOUCSABLE window does not need to obtain focus, nor does it need to receive various input events, and enables FLAG_NOT_TOUCH_MODAL at the same time.
The FLAG_NOT_TOUCH_MODAL system will pass the click event outside the current Window area to the underlying Window, and the events in the current Window area will be handled by themselves.
FLAG_SHOW_WHEN_LOCKED Turn on this mode to let the window display on the lock screen interface
2. Understand WindowManager in Android
The management of Window in Android is done through WindowManager. After creating PhoneWindow, WindowManager will be set up for the Window object. WindowManager is an interface that inherits the ViewManager interface. From here, it can be seen that the operation of Window is actually the operation of View. The implementation class of WindowManager is WindowMangerImpl, which is created by WindowManager through new.
3. The association between Window and WindowManagerImpl
The WindowManagerImpl instance can be obtained through the getSystemService of ContextImpl. The same ContextImpl obtains the same WindowManagerImpl object. After obtaining WindowMangerImpl, call the Window's setWindowManager method to establish a connection between Window and WindowManagerImpl.
The setWindowManager mainly completes the recreation of a WindowManagerImpl bound to the current Window based on the WindowManagerImpl instance, and assigns values to the properties mWindowManager in the Window
That is to say, on the Java layer, Window establishes the first step of contact with WindowManager, and assigns WindowManager in Activity, Dialog, etc. to the new WindowManagerImpl object.
Notice:Here is a singleton WindowManagerImpl object, combined with different Windows, and finally builds a non-singleton WindowManagerImpl object associated with Window.
4. Operation of Window
1. Add an operation, note that it is to add a new Window, not to operate on a view in a Window
Every window displayed in Android is actually the process of displaying the View to the screen. If we customize a layout to be displayed and get the View object, then just call the addView method of the WindowManagerImpl object. The WindowManagerImpl instance can be obtained through the getSystemService of ContextImpl.
WindowManagerImpl object, there is a singleton WindowManagerGlobal object in WindowManagerImpl. In each of the methods of WindowManagerImpl, the task execution process is passed to WindowManagerGlobal. During the delivery process, in addition to passing View and LayoutParams, the associated window objects in WindowManagerImpl are also passed together.
WindowManagerGlobal's addView method
In WindowMAnagerGlobal, judge the legality of view, LayoutParams and other parameters, create ViewRootImpl, add ViewRootImpl, View, LayoutParams to the corresponding ArayyList collection in WindowMAnagerGlobal, and then call the setView method of ViewRootImpl
ViewRootImpl
Inherited from the Handler class, it is a bridge for communication between native and Java layer View systems.
ViewRootImpl is created to save a reference to the thread that created it. When updating View during development, it will determine whether the current thread is the thread that created ViewRootImpl. If it is not, an exception will be thrown.
Generally, ViewRootImpl is created in the main thread, so an exception will be thrown when updating the UI in the child thread, because ViewRootImpl is created in the UI thread, not because only UI threads can update the UI.
If you modify the UI in the child thread before the onResume in the Activity, no exception will be thrown, because ViewRootImpl is created after onResume. At this time, the update of the UI needs to be updated through ViewRootImpl. Before onResume, the screen of the Activity is not displayed. Modifying the UI will only modify the UI in the layout, and the ViewRootImpl method will not be called to display it on the screen.
So it is concluded that only after the UI is displayed on the screen, when updating the UI, it will determine whether the thread is the thread that created the UI. If it does not match, an exception will be thrown. When updating the UI is not displayed on the screen, it will not make thread judgments.
ViewRootImpl's setView method:
- The setView method will first call the requestLayout() method, and the thread judgment is performed here. If the thread matches, scheduleTraversals() will be called to complete the measurement, layout, and drawing process of the View
- In the setView, the addToDisplay method in the IWindowSession object is remotely called, and information such as window is passed to the NMS. Call the addWindow method of the NMS to complete the display of the last window on the screen.
IWindowSession WindowManagerService
Here is the key to displaying the View on the screen, where it passes the View from the application process to the system process and then completes the display. The IWindowSession object in ViewRootImpl is obtained through the static method of WindowManagerGlobal getWindowSession(). In this method, the system service is obtained through IPC through the ServiceManager and Binder. WindowsManagerService is used to apply the remote proxy of the process, and then the WMS openSession() method is called through AIDL communication to obtain the remote proxy object of the IWindowSession interface implementation class Session class. The Session class is also a Binder, so it can be passed across processes.
In the addToDisplay method of the remote proxy of the Session, call the addToDisplay method of the Session through AIDL to pass the window information to the system process, and then call the addWindow method of AMS. AMS finally displays the View in the Window to the screen.
2. The delete operation is to delete a Window that already exists on the screen.
In the operation, first find the View to be deleted through findViewLocked, then find the ViewRootImpl of the corresponding Window through View, delete View, LayoutParams, and ViewRootImpl from the corresponding ArrayList, and then call the remove of Session through IPC, and call the removeWindow method of WMS to remove the View corresponding to the Window on the screen.
3. Update operation
, set new LayoutParams for the view, find the corresponding ViewRootImpl through findViewLocked, delete the old LayoutParams in the LayoutParams collection, add new LayoutParams in the original location of the collection, call the setLayoutParams of ViewRootImpl to complete the re-measurement, layout, and draw. Finally, call Session through IPC and then call WMS to complete the update of the window.
4. Add Window Code
The customized Window does not actively create the Window during the creation process, but is maintained by the system when it is displayed. This also reflects that Window is an abstract concept, and what needs to be processed in the end is still View.
private void addWindow() { TextView view = new TextView(this); ("Text"); (new () { @Override public void onClick(View v) { ("renxl", "onClick"); } }); (); // The View to be displayed can be newly created or can be obtained from the LayoutInflater from the xml layout mLayoutParams = new ( .MATCH_PARENT, .WRAP_CONTENT, 0, 0, ); // Must be = .FLAG_NOT_TOUCH_MODAL; // Choose one of three flags = .TYPE_TOAST; // type indicates priority = | ; = 100; // On the screen X-axis position = 300; // On the screen Y-axis position WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE); (view, mLayoutParams); // Add View to the interface} **Notice,If it is system level Window That is, priority exceeds 1999 of,Requires declaration of permissions** <uses-permission android:name=".SYSTEM_ALERT_WINDOW" />
5. Processing process of user touch screen event
WMS passes event IPC to Window, and the CallBack object inside it is called, which is the Activity or Dialog object or method. Finally, the event is passed to the View, and then the response view and corresponding window IPC are submitted to WMS through ViewRootImpl to complete the response display.
6. Common Window creation
1. Activity's Window creation process
In the Activity startup process, the Activity attach method assigns a new PhoneWindow to window, and setContentView passes layout to PhoneWindow. The layout View is loaded through the LayoutInflater's inflate method in PhoneWindow and added to the DecorView inside PhoneWindow. When onResume, the addView method of WindowManager is called to display the DecorView in Window to the screen through WMS.
Activity When creating Window, it implements the methods in the Window Callback interface. When Window receives a touch, it will call back the methods in Callback to pass events to the Activity. The corresponding distribution method in PhoneWindow will be called, and the methods in the DecordView will be called in PhoneWindow, and the events will be finally passed to the View.
The reason why guessing that events are passed from WMS to Window to Activity to Window is that such an extra layer of Activity is that developers can handle events in Activity and do not necessarily have to pass them to View
2. Dialog's Window creation process
In the same Activity, when instantiating the Dialog object, create a PhoneWindow, and when calling the WMS' addView method through AIDL, add the View to the screen.
3. Toast's Window creation process
Toast does not actively create Window during the creation process, but the Toast window is maintained by the system when it is displayed. This also reflects that Window is an abstract concept, and what needs to be processed in the end is still View.
Toast's work project requires the three parts of TN NMS WMS to be completed in collaboration. IN is also a Binder. In NMS, TN is called remotely access, and TN is called WMS is also remotely called.
NMS is NotificationManagerService
Toast's work process is divided into two steps
- The first step is to create an object of Binder type TN in the current thread, remotely call the enqueue method in NMS to pass TN to NMS, NMS remotely call the show method of TN, and the show method in TN is run in the currently applied Binder thread pool. The process is switched to the main thread through the Handler's post series method, and the main thread then calls the methods in WMS to complete the show process through WindowManager.
- After calling TN's show method in NMS, it will delay sending a message with the time to Toast display time through its internal Handler. After receiving the message, the Handler in NMS calls TN's hide method (remote call process). The hide method in TN will remotely call the hide method in WMS through WindowManager to hide Toast. Complete the whole process.
7. Summary
Each window displayed on the screen requires that the window and View are combined with each other, and there can be multiple Window in the screen. The Views mentioned below are root Views included in a Window
The creation of windows and the addition, deletion and update of Views are implemented by WindowManager. The operation of windows in WindowManager uses the IPC remote request method in IWindowSession through the IPC remote request method in IWindowSession and then calls the corresponding method of WMS to implement the current window operation on the screen.
Each Window corresponds to a ViewRootImpl. The window manages the view through the corresponding ViewRootImpl.
When there is user interaction on the screen, WMS will pass the event to the Window of the corresponding interface. The Window will call the corresponding CallBack of the current interface to handle the event
WindowManager is an interface, and the implementation class is WindowManagerImpl. WindowManagerImpl is used to complete the operation through WindowMAnagerGlobal. Typical bridge mode
Adding Window does not show the problem
Due to the domestic customization of ROMs, many models will prohibit the creation of floating windows by default. Therefore, if it is not displayed, check whether the application permission is closed.
- Android 6.0 has added switch settings for permissions, and the floating window permissions are turned off by default.
- Some domestic customized Rom 6.0 can be set before setting permission switches, and the floating window permissions are closed by default.
Problem solving
= .TYPE_TOAST;
Set type to TYPE_TOAST , there is no restriction on TYPE_TOAST in the source code.
On domestic customized Rom, only a few models will not be able to get the monitoring event of the View when setting TYPE_TOAST, and the display is OK.
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for your study or work. Thank you for your support.