Activity's Window and WindowManager creation process (1)

On page 1
, we start to analyze the creation process of Activity's Window and WindowManager. In the Activity's attach function, not only Context, but also Window and WindowsManager objects will be created. Therefore, we will start the analysis from the Activity's attach function:
1 final void attach( Context context, ActivityThread aThread,
2 Instrumentation instr, IBinder token, int ident,
3 Application application, Intent intent, ActivityInfo info,
4 CharSequence title, Activity parent, String id,
5 NonConfigurationInstances lastNonConfigurationInstances,
6 Configuration config) {
7 attachBaseContext(context) ;
8
9 mFragments.attachActivity(this, mContainer, null);
10        
11         mWindow = PolicyManager.makeNewWindow(this);
12         mWindow.setCallback(this);
13         mWindow.getLayoutInflater().setPrivateFactory(this);
14         if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
15             mWindow.setSoftInputMode(info.softInputMode);
16         }
17         if (info.uiOptions != 0) {
18             mWindow.setUiOptions(info.uiOptions);
19         }
20         mUiThread = Thread.currentThread();
21        
22         mMainThread = aThread;
23         mInstrumentation = instr;
24         mToken = token;
25         mIdent = ident;
26         mApplication = application;
27         mIntent = intent;
28         mComponent = intent.getComponent();
29         mActivityInfo = info;
30         mTitle = title;
31         mParent = parent;
32         mEmbeddedID = id;
33         mLastNonConfigurationInstances = lastNonConfigurationInstances;
34
35         mWindow.setWindowManager(
36                 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
37                 mToken, mComponent.flattenToString(),
38                 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
39         if (mParent != null) {
40 mWindow.setContainer(mParent.getWindow());
41 }
42 mWindowManager = mWindow.getWindowManager();
43 mCurrentConfig = config;
44 }
Line 11 (Activity->attach) will call PolicyManager's makeNewWindow function to create this Activity For a Window, for a detailed analysis of the PolicyManager's makeNewWindow function, please refer to the page2 file.
Private Window mWindow;
Line 12 (Activity->attach) will set the callback of mWindow to the current activity, so that mWindow can pass some events to acticity. Execute
Lines 13-19 (Activity->attach) will set some properties of Window, we don't care about it.
Lines 35-38 (Activity->attach) will call the setWindowManager function of Window. For a detailed analysis of the setWindowManager function, please refer to the page6 file .Lines
39-41 (Activity->attach) will determine whether the mParent of the Activity is not empty. If it is not empty, it will be set to the Window of the mParent for the setContainer of the Window. For a detailed analysis of the setContainer function, please refer to the page11 file .
    Line 42 (Activity->attach) will call Window's getWindowManager to get WindowManager, so that each Activity instance will hold a WindowManager object. The definition of the makeNewWindow function of
page2 PolicyManager is as follows: public static Window makeNewWindow(Context context) {         return sPolicy.makeNewWindow(context);     } The makeNewWindow function of PolicyManager simply calls the makeNewWindow function of the static member variable sPolicy. The definition and initialization of sPolicy are as follows:     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 be loaded", ex);
} catch (InstantiationException ex) {
    throw new RuntimeException(
            POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
} catch (IllegalAccessException ex) {
    throw new RuntimeException(
            POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
}
    }

You can see that sPolicy is actually loaded com.android.internal.policy.impl. Policy class, why load classes dynamically? Why not initialize a Policy class directly? Is this the policy pattern???????

So let's take a look at the implementation of the makeNewWindow function of com.android.internal.policy.impl.Policy:
public Window makeNewWindow(Context context) {
        return new PhoneWindow(context);
    }
just new a PhoneWindow and return. For the construction process of PhoneWindow, please refer to the page3 file.
On page3
, let's take a look at the creation process of PolicyManager. Let's first look at the inheritance system of the PolicyManager class:
public class PhoneWindow extends Window implements MenuBuilder.Callback
public abstract class Window

The constructor of PhoneWindow is as follows :
1 public PhoneWindow(Context context) {
2 super(context);
3 mLayoutInflater = LayoutInflater.from(context);
4 }
Line 2 (PhoneWindow->PhoneWindow) will call the constructor of the parent class, the constructor of the Window class is as follows :
    public Window(Context context) {
        mContext = context;
    }
    The constructor of the Window class does nothing but initialize mContext. This means that Window will hold a Context instance.
    Line 3 (PhoneWindow->PhoneWindow) will Call the from function of LayoutInflater to obtain a LayoutInflater object and initialize the member variable mLayoutInflater. For a detailed analysis of the from function of LayoutInflater, please refer to the page4 file. On page 4 , we analyze the creation process of LayoutInflater, that is, the calling process of the from function of LayoutInflater
: 1 public static LayoutInflater from(Context context) {     2 LayoutInflater LayoutInflater =     3 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);     4 if (LayoutInflater == null) {     5 throw new AssertionError("LayoutInflater not found.");






    6 }
    7 return LayoutInflater;
    8 }
    Lines 2-3 (LayoutInflater->from) will call the getSystemService of Context to get a LAYOUT_INFLATER_SERVICE service, oh!!! The parsing layout exists as a service, that is Binder!
    Here Context is actually an Activity object, so the getSystemService function of Activity is actually called here. The definition of the getSystemService function of Activity is as follows:
    1 public Object getSystemService(String name) {
    2 if (getBaseContext() == null) {
    3 throw new IllegalStateException(
    4 "System services not available to Activities before onCreate()");
    5 }
    6
    7 if (WINDOW_SERVICE.equals(name)) {
    8 return mWindowManager;
    9 } else if (SEARCH_SERVICE.equals(name)) {
    10 ensureSearchManager();
    11 return mSearchManager;
    12 }
    13 return super.getSystemService(name);
    14 }
    Line 13 (Activity->getSystemService) will call the parent class ContextThemeWrapper The getSystemService function of the ContextThemeWrapper class is defined as follows:
1 @Override public Object getSystemService(String name) {
2 if (LAYOUT_INFLATER_SERVICE.equals(name)) {
3 if (mInflater == null) {
4 mInflater = LayoutInflater.from (mBase).cloneInContext(this);
5 }
6 return mInflater;
7 }
8 return mBase.getSystemService(name);
9 }
Lines 2-7 (ContextThemeWrapper->getSystemService) will call LayoutInflater.from(mBase) again, I rely, is this not an infinite loop? Note, this is mBase, mBase is actually It is a ContextImpl type, so the
getSystemService function of ContextImpl will be called here. For a detailed analysis of the getSystemService function of ContextImpl, please refer to the page5 file.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326173598&siteId=291194637