The creation process of Activity's Window and WindowManager (2)

page5
In this article, we analyze the getSystemService function of ContextImpl,
1 public Object getSystemService(String name) {
2 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
3 return fetcher == null ? null : fetcher.getService(this) ;
4 }
The second line (ContextImpl->getSystemService) SYSTEM_SERVICE_MAP is defined as follows:
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = new HashMap<String, ServiceFetcher>();
    During the loading process of ContextImpl, SYSTEM_SERVICE_MAP will be initialized, here we are Only care about the LAYOUT_INFLATER_SERVICE service, the relevant code is as follows:
        static {
            ............
            registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
                    public Object createService(ContextImpl ctx) {
                        return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
                    }});

            ............
        }
ContextImpl类的registerService函数的定义如下:
1     private static int sNextPerContextServiceCacheIndex = 0;
    2     private static void registerService(String serviceName, ServiceFetcher fetcher) {
    3         if (!(fetcher instanceof StaticServiceFetcher)) {
    4             fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
    5         }
    6         SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
    7     }
    The registerService function is easy to understand.
    Let’s go back to the third line of getSystemService (ContextImpl->getSystemService), where the getService function of ServiceFetcher will be called. ServiceFetcher is an inner class of ContextImpl. The getService function of ServiceFetcher is defined as follows:
    1 public Object getService( ContextImpl ctx) {
    2 ArrayList<Object> cache = ctx.mServiceCache;
    3 Object service;
    4 synchronized (cache) {
    5 if (cache.size() == 0) {
    6 // Initialize the cache vector on first access.
    7 // At this point sNextPerContextServiceCacheIndex
    8 // is the number of potential services that are
    9 // cached per-Context.
    10                     for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
    11                         cache.add(null);
    12                     }
    13                 } else {
    14                     service = cache.get(mContextCacheIndex);
    15                     if (service != null) {
    16                         return service;
    17                     }
    18                 }
    19                 service = createService(ctx);
    20                 cache.set(mContextCacheIndex, service);
    21                 return service;
    22             }
    23         }
    Lines 5-18 (ServiceFetcher->getService) will try to fetch it in the cache.
    Line 19 (ServiceFetcher->getService) will call the createService function to create a Service.
    In fact, what is called here is the sentence
    return PolicyManager.makeNewLayoutInflater(ctx .getOuterContext());
    Let's take a look at the implementation of PolicyManager's makeNewLayoutInflater function:
    public static LayoutInflater makeNewLayoutInflater(Context context) {
        return sPolicy.makeNewLayoutInflater(context);
    }
    Remember this logic? This will lead to com. The call of the makeNewLayoutInflater function of android.internal.policy.impl.Policy is defined as follows:
        public LayoutInflater makeNewLayoutInflater(Context context) {
            return new PhoneLayoutInflater(context);
        }
        FUCK, after such a big circle, a new PhoneLayoutInflater object will finally be created. Therefore, we know that what Window has is actually a PhoneLayoutInflater object.


    Line 20 (ServiceFetcher->getService) will set the newly created Service to the cache Go in.
   page6
In this article, we analyze the implementation of Window's setWindowManager function, in which a WindowManager will be created for the Window.
The definition of Window's setWindowManager function is as follows:
1 public void setWindowManager(WindowManager wm, IBinder appToken , String appName,
    2 boolean hardwareAccelerated) {
    3 mAppToken = appToken;
    4 mAppName = appName;
    5 mHardwareAccelerated = hardwareAccelerated
    6 || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
    7 if (wm == null) {
    8 wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
    9 }
    10 mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    11 }
    The third line (Window->setWindowManager) will save the activity's token
    fourth Line (Window->setWindowManager) will save appName
    Lines 5-6 (Window->setWindowManager) determine whether hardware acceleration is required, and whether the condition is whether the user displays the option to activate or the system supports
    Lines 7-9 (Window->setWindowManager) ) will obtain the WINDOW_SERVICE service through mContext. For detailed analysis, please refer to the page7 file.
    Line 10 (Window->setWindowManager) will call the createLocalWindowManager function of WindowManagerImpl to get a WindowManagerImpl object, and use this object to initialize the member variable mWindowManager. The definition of the createLocalWindowManager function is as follows :
        public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
            return new WindowManagerImpl(mDisplay, parentWindow);
        } The createLocalWindowManager
    function just creates another WindowManagerImpl object, but the object has a parentWindow. On
page 7,
we analyze the acquisition process of the WINDOW_SERVICE service of ContextImpl, which is obtained by calling the getSystemService function. We have already analyzed the implementation logic of the
getSystemService function. In fact, it will be executed here in the end:
1 registerService(WINDOW_SERVICE, new ServiceFetcher() {
    2 public Object getService(ContextImpl ctx) {
    3 Display display = ctx.mDisplay;
    4 if (display == null) {
    5 DisplayManager dm = (DisplayManager)ctx.getOuterContext().getSystemService(
    6 Context.DISPLAY_SERVICE);
    7 display = dm.getDisplay(Display.DEFAULT_DISPLAY);
    8 }
    9 return new WindowManagerImpl(display);
    10 }});
        Is it very familiar.
    Lines 5-6 (ContextImpl->registerService) are again Get the DISPLAY_SERVICE service by calling the getSystemService function, don't say it, look at the following code:
            registerService(DISPLAY_SERVICE, new ServiceFetcher() {
                    @Override
                    public Object createService(ContextImpl ctx) {
                        return new DisplayManager(ctx.getOuterContext());
                    }} );
    There will be a new DisplayManager. For the construction process of DisplayManager, please refer to the page8 file.
    Line 7 (ContextImpl->registerService) will call the getDisplay function of DisplayManager. For a detailed analysis of the getDisplay function, please refer to the page9 file.

Line 9 (ContextImpl->registerService) ) will use the newly obtained Display object to create a new WindowManagerImpl and return it. The constructor of the WindowManagerImpl function is as follows:
    public WindowManagerImpl(Display display) {
this(display, null);
    }

    private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
    }
page8
Here we look at the construction process of DisplayManager, the constructor of DisplayManager is as follows:
1 public DisplayManager(Context context) {
    2 mContext = context;
    3 mGlobal = DisplayManagerGlobal.getInstance();
    4 }
    The second line (DisplayManager->DisplayManager) will save the Context
    , and the third line (DisplayManager->DisplayManager) will call the DisplayManagerGlobal.getInstance() function to get the DisplayManagerGlobal instance, the getInstance function of DisplayManagerGlobal It is defined as follows:
    1 public static DisplayManagerGlobal getInstance() {
    2 synchronized (DisplayManagerGlobal.class) {
    3 if (sInstance == null) {
    4 IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
    5 if (b != null) {
    6 sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
    7 }
    8 }
    9 return sInstance;
    10 }
    11 }
    From the definition of the getInstance function, we can know that the main logic of getInstance is to obtain the DISPLAY_SERVICE service through ServiceManager, which is related to Binder. After obtaining the DISPLAY_SERVICE service, this service will be used to create a DisplayManagerGlobal object,
    DisplayManagerGlobal's The constructor is defined as follows:
    private DisplayManagerGlobal(IDisplayManager dm) {
        mDm = dm;
    }




Guess you like

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