In the previous article, we analyzed the creation process of the runtime context of the Android application window. It follows that each activity component has an associated Contextimpl object, and It also associates a window object to describe a specific application window. It is also known that activity is nothing more than a highly abstract UI component, and that its specific UI implementations are actually implemented by a number of other objects. In this article, we will analyze the creation process of the Android application window object in detail.
A brief introduction to the framework of the previous Android application window (activity) and a learning plan can be found on the phone platform, the actual type of the window object associated with the activity component is Phonewindow, and the latter is inherited from a window class. The relationship between activity, window, and Phonwwindow three classes can be referenced in the Android application window (activity) Implementation Framework brief introduction and Learning Plan in Figure 3 and Figure 5. To facilitate the next description of the creation of an application window of type Phonewindow, we take these two graphs, as shown in Figure 1 and figure 2 below:
Figure 1 class diagram of activity and window
Figure 2 class diagram for Windows and Phonewindow
The descriptions of the classes covered in the two diagrams can refer to the Android application window (activity) Implementation Framework brief introduction and the Learning Plan article, this paper mainly from the Android application window creation process to understand the activity, The relationship between window and Phonwwindow three classes.
An analysis of the creation process from the runtime context of the Android application window (activity) can be known, A Phonewindow object associated with the activity component is created from the member function attach of the activity class, as shown in Figure 3:
Figure 3 The Android application window creation process
This process can be divided into 9 steps, and then we will analyze each step in detail.
Step 1. Activity.attach
Copy Code code as follows:
public class activity extends Contextthemewrapper
Implements Layoutinflater.factory,
Window.callback, Keyevent.callback,
Oncreatecontextmenulistener, Componentcallbacks {
......
Private Window Mwindow;
......
final void attach (context, Activitythread athread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent Intent, Activityinfo info,
Charsequence title, activity parent, String ID,
Object Lastnonconfigurationinstance,
Hashmap<string,object> Lastnonconfigurationchildinstances,
Configuration config) {
......
Mwindow = Policymanager.makenewwindow (this);
Mwindow.setcallback (this);
if (Info.softinputmode!= WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
Mwindow.setsoftinputmode (Info.softinputmode);
}
......
Mwindow.setwindowmanager (null, Mtoken, mcomponent.flattentostring ());
......
}
......
}
This function is defined in the file Frameworks/base/core/java/android/app/activity.java.
We have already analyzed the implementation of this function in the creation process analysis of the runtime context of the previous Android application window (activity), where we focus only on the code associated with the application window creation.
The function first calls the static member function Makenewwindow of the Policymanager class to create an application window of type Phonewindow and is saved in the member variable Mwindow of the Activity class. With this type of Phonewindow application window, the function then calls its member functions Setcallback, Setsoftinputmode, and Setwindowmanager to set the window callback interface, The display mode of the soft keyboard input area and the local window manager.
The member functions of the Phonewindow class, Setcallback, Setsoftinputmode, and Setwindowmanager, are inherited from the parent class window, so Next we continue to analyze the static member function Makenewwindow of the Policymanager class, and the implementation of the member functions Setcallback, Setsoftinputmode, and Setwindowmanager of the window class.
Step 2. Policymanager.makenewwindow
Copy Code code as follows:
Public final class Policymanager {
private static final String Policy_impl_class_name =
"Com.android.internal.policy.impl.Policy";
private static final Ipolicy Spolicy;
static {
Pull in the actual implementation of the policy at Run-time
try {
Class Policyclass = Class.forName (policy_impl_class_name);
Spolicy = (ipolicy) policyclass.newinstance ();
catch (ClassNotFoundException ex) {
throw New RuntimeException (
Policy_impl_class_name + "could not to be loaded", ex);
catch (Instantiationexception ex) {
throw New RuntimeException (
Policy_impl_class_name + "could not to be instantiated", ex);
catch (Illegalaccessexception ex) {
throw New RuntimeException (
Policy_impl_class_name + "could not to be instantiated", ex);
}
}
......
The static methods to spawn new Policy-specific objects
public static Window Makenewwindow (context context) {
return Spolicy.makenewwindow (context);
}
......
}
This function is defined in the file Frameworks/base/core/java/com/android/internal/policy/policymanager.java.
Policymanager is a window management policy class that, when used for the first time, creates a policy class instance and is saved in a static member variable Spolicy. The window management strategy for the Policymanager class later is implemented through this policy class instance, for example, The static member function of the Policymanager class Makenewwindow is to create a concrete application window by calling the member function Makenewwindow of this policy class instance.
Next, we continue to analyze the implementation of the member function Makenewwindow of the policy class.
Step 3. Policy.makenewwindow
Copy Code code as follows:
public class Policy implements Ipolicy {
......
Public Phonewindow Makenewwindow (context context) {
Return to New Phonewindow (context);
}
......
}
This function is defined in the file Frameworks/base/policy/src/com/android/internal/policy/impl/policy.java.
The implementation of the member function Makenewwindow of the policy class is simple, it simply creates a Phonewindow object and returns it to the caller.
Next, we continue to analyze the implementation of the constructor for the Phonewindow class so that you can understand the creation of an application window of type Phonewindow.
Step 4. New Phonewindow
Copy Code code as follows:
public class Phonewindow extends Window implements Menubuilder.callback {
......
This is the top-level view of the window, containing the window decor.
Private Decorview Mdecor;
This is the view in which the window contents are placed. It is either
Mdecor itself, or a child of Mdecor where the contents go.
Private ViewGroup mcontentparent;
......
Private Layoutinflater Mlayoutinflater;
......
Public Phonewindow {
Super (context);
Mlayoutinflater = Layoutinflater.from (context);
}
......
}
This function is defined in the file Frameworks/base/policy/src/com/android/internal/policy/impl/phonewindow.java.
The constructor of the Phonewindow class is simple, it first invokes the constructor of the parent class window to perform some initialization, and then calls the static member function of Layoutinflater to create a Layoutinflater instance. and is saved in the member variable Mlayoutinflater. In this way, the Phonewindow class can later create a view of the application window through the member variable Mlayoutinflater, which is described using a member variable Mdecor of type Decorview. The Phonewindow class also has another member variable of type ViewGroup mcontentparent that describes a view container that holds the contents of the view described by the member variable Mdecor. But the container may also point to the Mdecor itself. In a later article, we further analyze the creation of the view of the application window of type Phonewindow.
The Window's constructor is defined in the file Frameworks/base/core/java/android/view/window.java, its implementation is simple, but its member variable mcontext is initialized, as follows:
Copy Code code as follows:
Public abstract class Window {
......
Private final context Mcontext;
......
Public Window {
Mcontext = context;
}
......
}
As you can see from the previous call procedure, the parameter context describes the activity component that is starting and saves it to the member variable mcontext of the window class, which allows the window class to access the resources associated with the activity component.
After this step has been completed, go back to the previous Stage 1, which is the member function attach of the activity class, Next we continue to call the Phonewindow object created earlier to set the window callback interface from the member function Setcallback inherited from the parent class window, so we continue to parse the implementation of the member function Setcallback of the window class.
Step 5. Window.setcallback
Copy Code code as follows:
Public abstract class Window {
......
Private Callback Mcallback;
......
/**
* Set the Callback interface for this window, used to intercept key
* Events and other dynamic operations in the window.
*
* @param callback the desired callback interface.
*/
public void Setcallback (Callback Callback) {
Mcallback = callback;
}
......
}
This function is defined in the file Frameworks/base/core/java/android/view/window.java.
The activity component being started sets the callback interface it implements to the member variable mcallback of the parent class window of the Phonewindow object it is associated with. So when the Phonewindow object receives the IO input events that the system distributes to it, such as keyboard and touchscreen events, it is forwarded to the activity component associated with it, This can be referred to the previous Android application keyboard (keyboard) Message processing mechanism analysis of the article.
After this step has been completed, go back to the previous Stage 1, which is the member function attach of the activity class, You will then continue to call the Phonewindow object created earlier to set the display mode of the soft keyboard input region of the application window from the member function Setsoftinputmode inherited from the parent class window, so Next we continue to analyze the implementation of the member function Setsoftinputmode of the window class.
Step 6. Window.setsoftinputmode
Copy Code code as follows:
Public abstract class Window {
......
Private Boolean mhassoftinputmode = false;
......
public void Setsoftinputmode (int mode) {
Final Windowmanager.layoutparams attrs = GetAttributes ();
if (mode!= WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
Attrs.softinputmode = mode;
Mhassoftinputmode = true;
} else {
Mhassoftinputmode = false;
}
if (mcallback!= null) {
Mcallback.onwindowattributeschanged (ATTRS);
}
}
......
}
This function is defined in the file Frameworks/base/core/java/android/view/window.java.
Parameter mode has soft_input_state_unspecified, soft_input_state_unchanged, Soft_input_state_hidden, SOFT_INPUT_STATE_ALWAYS _hidden, soft_input_state_visible, and soft_input_state_always_visible are all six values that describe the display mode of the soft keyboard input area of the window, and their meanings are as follows:
1. soft_input_state_unspecified: The display status of the soft keyboard input area is not specified.
2. soft_input_state_unchanged: Do not change the display state of the soft keyboard input area.
3. Soft_input_state_hidden: Hides the soft keyboard input area when appropriate, for example, when the user navigates to the current window.
4. Soft_input_state_always_hidden: When the window gets focus, the soft keyboard input area is always hidden.
5. soft_input_state_visible: Displays the soft keyboard input area when appropriate, for example, when the user navigates to the current window.
6. soft_input_state_always_visible: When the window gets the focus, the soft keyboard input area is always displayed.
When the value of parameter mode is not equal to soft_input_state_unspecified, the display mode of the specified soft keyboard input region for the current window is indicated. The member function Setsoftinputmode of the window class then sets the value of the member variable Mhassoftinputmode to TRUE. And the display mode is saved in the member variable softinputmode of a Windowmanager.layoutparams object that describes the window layout properties, otherwise the value of the member variable Mhassoftinputmode is set to false.
After setting the display mode for the soft keyboard input area of the window, if the member variable mcallback of the Windows class points to a window callback interface, The member function Setsoftinputmode of the window class also invokes its member function onwindowattributeschanged to notify the activity component associated with the window, and its window layout properties have changed.
After this step has been completed, go back to the previous Stage 1, which is the member function attach of the activity class, You will then continue to call the Phonewindow object created earlier to set the local window manager for the application window from the member function Setwindowmanager inherited from the parent class window, so Next we continue to analyze the implementation of the member function Setwindowmanager of the window class.
Step 7. Window.setwindowmanager
Copy Code code as follows:
Public abstract class Window {
......
Private WindowManager Mwindowmanager;
Private IBinder Mapptoken;
Private String Mappname;
......
public void Setwindowmanager (WindowManager wm,
IBinder Apptoken, String appName) {
Mapptoken = Apptoken;
Mappname = AppName;
if (wm = = null) {
WM = Windowmanagerimpl.getdefault ();
}
Mwindowmanager = new Localwindowmanager (WM);
}
......
}
This function is defined in the file Frameworks/base/core/java/android/view/window.java.
The parameter apptoken is used to describe which activity component is currently being processed by the window, which is a binder proxy object, A binder local object of type Activityrecord created on this side of the Activitymanagerservice is referenced. A brief introduction to the activity initiation process from the previous Android application and a list of learning plans a series of articles can be learned that each started up the activity component on the Activitymanagerservice side, has a corresponding Activityrecord object that describes the running state of the activity component. This binder proxy object is saved in the member variable mapptoken of the window class, so that the window currently being processed can know what the activity component is associated with it.
The parameter appname is used to describe the name of the activity component associated with the window that is currently being processed, and this name is saved in the member variable mappname in the window class.
Parameter wm is used to describe a window manager. You can tell from the previous call procedure that the value of the parameter wm that is passed here equals null, so the function first invokes the static member function Getdefault of the Windowmanagerimpl class to obtain a default window manager. With this window manager, the function then uses it to create a local window manager, a Localwindowmanager object, to maintain the application window that is currently being processed.
Next, we first analyze the implementation of the static member function Getdefault of the Windowmanagerimpl class, then analyze the creation process of the local window manager, that is, the implementation of the constructor of the Localwindowmanager class.
Step 8. Windowmanagerimpl.getdefault
Copy Code code as follows:
public class Windowmanagerimpl implements WindowManager {
......
public static Windowmanagerimpl Getdefault ()
{
return mwindowmanager;
}
......
private static Windowmanagerimpl Mwindowmanager = new Windowmanagerimpl ();
}
This function is defined in the file Frameworks/base/core/java/android/view/windowmanagerimpl.java.
The implementation of the static member function Getdefault of the Windowmanagerimpl class is simple, and it simply returns a Windowmanagerimpl object that the static member variable Mwindowmanager points to the caller. This Windowmanagerimpl object implements the WindowManager interface, so it can be used to manage the application window.
After this step has been completed, go back to the previous stage 7, the member function Setwindowmanager of the window class, and then use the previous Windowmanagerimpl object to create a local window manager. is a Localwindowmanager object.
Step 9. New Localwindowmanager
Copy Code code as follows:
Public abstract class Window {
......
Private final context Mcontext;
......
Private class Localwindowmanager implements WindowManager {
Localwindowmanager (WindowManager wm) {
Mwindowmanager = WM;
Mdefaultdisplay = Mcontext.getresources (). Getdefaultdisplay (
Mwindowmanager.getdefaultdisplay ());
}
......
Private final WindowManager Mwindowmanager;
Private final Display Mdefaultdisplay;
}
......
}
This function is defined in the file Frameworks/base/core/java/android/view/window.java.
The constructor of the Localwindowmanager class first saves the Windowmanagerimpl object described by the parameter wm to its member variable Mwindowmanager, so that the window management work is then entrusted to it for processing.
The constructor of the Localwindowmanager class then obtains a display object by using the member function Getdefaultdisplay of a Windowmanagerimpl object described by the member variable Mwindowmanager. Used to describe the system screen properties.
Because the previously obtained display object describes the global screen properties, and the window currently being processed may have some customizable screen properties configured, The constructor of the Localwindowmanager class needs to further adjust the screen properties described in the previously obtained display object so that it can be used for the window currently being processed. The constructor of the Localwindowmanager class first obtains a resources object through the member function getresources of the External class window's member variable mcontext. The member function Getdefaultdisplay of the resources object is then invoked to adjust the screen properties described by the previously obtained display object. The final adjustment of the finished display object is saved in the member variable mdefaultdisplay of the Localwindowmanager class.
As you can see from step 4 above, Class window's member variable Mcontext describes an activity component associated with the current window. The member function getresources of the activity class is continued from the parent class Contextwrapper, which is implemented in the file frameworks/base/core/java/android/content/ Contextwrapper.java, as follows:
Copy Code code as follows:
public class Contextwrapper extends context {
Context Mbase;
......
@Override
Public Getresources ()
{
return mbase.getresources ();
}
......
}
From the creation process analysis of the runtime context of the previous Android application window (activity), you know that the member variable of the Contextwrapper class mbase points to a Contextimpl object, Used to describe the running context of an activity component. By calling the member function of this Contextimpl object getresources, you can gain access to the resource information of an activity component through this resources object This allows you to obtain the screen properties that it configures.
At this point, we analyze the process of creating the application window object that is associated with an activity component. From the process of analysis you can know:
1. The type of application window object associated with an activity component is phonewindow.
2. This type of Phonewindow application window is maintained through a local window manager of type Localwindowmanager.
3. This type of Localwindowmanager local window manager maintains the application window through a window manager of type Windowmanagerimpl.
4. This type of Phonewindow application window has a View object of type Decorview, which is the UI that is really used to describe an activity component.
In the next article, we will continue to analyze the creation process of the view objects inside the application window, so stay tuned!