当前位置:操作系统 > 安卓/Android >>

Android窗口管理服务WindowManagerService组织窗口的方式分析

  1.  增加AppWindowToken
 
       从前面Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析一文可以知道,一个Activity组件在启动的过程中,ActivityManagerService服务会调用调用WindowManagerService类的成员函数addAppToken来为它增加一个AppWindowToken,如下所示:
 
[java]  
public class WindowManagerService extends IWindowManager.Stub    
        implements Watchdog.Monitor {    
    ......    
    
    /**  
     * Mapping from a token IBinder to a WindowToken object.  
     */    
    final HashMap<IBinder, WindowToken> mTokenMap =    
            new HashMap<IBinder, WindowToken>();    
    
    /**  
     * The same tokens as mTokenMap, stored in a list for efficient iteration  
     * over them.  
     */    
    final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();    
    ......    
    
    /**  
     * Z-ordered (bottom-most first) list of all application tokens, for  
     * controlling the ordering of windows in different applications.  This  
     * contains WindowToken objects.  
     */    
    final ArrayList<AppWindowToken> mAppTokens = new ArrayList<AppWindowToken>();    
    ......    
    
    public void addAppToken(int addPos, IApplicationToken token,    
            int groupId, int requestedOrientation, boolean fullscreen) {    
        ......    
    
        synchronized(mWindowMap) {    
            AppWindowToken wtoken = findAppWindowToken(token.asBinder());    
            if (wtoken != null) {    
                ......    
                return;    
            }    
            wtoken = new AppWindowToken(token);    
            ......    
            mAppTokens.add(addPos, wtoken);    
            ......    
            mTokenMap.put(token.asBinder(), wtoken);    
            mTokenList.add(wtoken);    
    
            ......   
        }    
    }    
    
    ......    
}    
       这个函数定义在文件frameworks/base/services/java/com/android/server/WindowManagerService.java中。
       WindowManagerService类有三个成员变量mTokenMap、mTokenList和mAppTokens,它们都是用来描述系统中的窗口的。
 
       成员变量mTokenMap指向的是一个HashMap,它里面保存的是一系列的WindowToken对象,每一个WindowToken对象都是用来描述一个窗口的,并且是以描述这些窗口的一个Binder对象的IBinder接口为键值的。例如,对于Activity组件类型的窗口来说,它们分别是以用来描述它们的一个ActivityRecord对象的IBinder接口保存在成员变量mTokenMap所指向的一个HashMap中的。
 
       成员变量mTokenList指向的是一个ArrayList,它里面保存的也是一系列WindowToken对象,这些WindowToken对象与保存在成员变量mTokenMap所指向的一个HashMap中的WindowToken对象是一样的。成员变量mTokenMap和成员变量mTokenList的区别就在于,前者在给定一个IBinder接口的情况下,可以迅速指出是否存在一个对应的WindowToken对象,而后者可以迅速遍历WindowManagerService服务中的WindowToken对象。
 
       成员变量mAppTokens指向的也是一个ArrayList,不过它里面保存的是一系列AppWindowToken对象,每一个AppWindowToken对象都是用来描述一个Activity组件窗口的,而这些AppWindowToken对象是以它们描述的窗口的Z轴坐标由小到大保存在这个ArrayList中的,这样我们就可以通过这个ArrayList来从上到下或者从下到上地遍历系统中的所有Activity组件窗口。由于这些AppWindowToken对象所描述的Activity组件窗口也是一个窗口,并且AppWindowToken类是从WindowToken继承下来的,因此,这些AppWindowToken对象还会同时被保存在成员变量mTokenMap所指向的一个HashMap和成员变量mTokenList所指向的一个ArrayList中。
 
       理解了WindowManagerService类的这三个成员变量的含义之后,它的成员函数addAppToken的实现就好理解了,其中,参数token指向的便是用来描述正在启动的Activity组件所对应的一个ActivityRecord对象,而参数addPos用来描述该Activity组件在堆栈中的位置,这个位置同时也是接下来要创建的AppWindowToken对象在WindowManagerService类的mTokenList所描述的一个ArrayList中的位置。
 
       WindowManagerService类的成员函数addAppToken首先调用另外一个成员函数findAppWindowToken来在成员变量mTokenMap所描述的一个HashMap检查是否已经存在一个AppWindowToken。如果已经存在的话,那么WindowManagerService类的成员函数addAppToken就什么也不做就返回了,否则的话,就会使用参数token来创建一个AppWindowToken对象,并且会将该AppWindowToken对象分别保存在WindowManagerService类的成员变量mTokenMap、mTokenList和mAppTokens中。
 
       2. 删除AppWindowToken
 
       删除AppWindowToken是通过调用WindowManagerService类的成员函数removeAppTokensLocked来实现的,如下所示:
 
[java]  
public class WindowManagerService extends IWindowManager.Stub    
        implements Watchdog.Monitor {    
    ......    
    
    private void removeAppTokensLocked(List<IBinder> tokens) {  
        // XXX This should be done more efficiently!  
        // (take advantage of the fact that both lists should be  
        // ordered in the same way.)  
        int N = tokens.size();  
        for (int i=0; i<N; i++) {  
            IBinder token = tokens.get(i);  
            final AppWindowToken wtoken = findAppWindowToken(token);  
            if (!mAppTokens.remove(wtoken)) {  
                ......  
                i--;  
                N--;  
            }  
补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,