`
zzu_007
  • 浏览: 22516 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Activity的Window和WindowManager的创建过程(二)

阅读更多
page5
在这篇文章中, 我们分析一下ContextImpl的getSystemService函数,
1     public Object getSystemService(String name) {
2         ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
3         return fetcher == null ? null : fetcher.getService(this);
4     }
第2行(ContextImpl->getSystemService)SYSTEM_SERVICE_MAP的定义如下:
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = new HashMap<String, ServiceFetcher>();
    在ContextImpl加载过程中, 会初始化SYSTEM_SERVICE_MAP, 我们这里只关心LAYOUT_INFLATER_SERVICE服务, 相关代码如下:
        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     }
    registerService函数很好理解吧.
    我们回到getSystemService的第3行(ContextImpl->getSystemService), 这里会调用ServiceFetcher的getService函数, ServiceFetcher是ContextImpl的一个内部类, ServiceFetcher的getService函数定义如下:
    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         }
    第5-18行(ServiceFetcher->getService)会尝试在cache里取.
    第19行(ServiceFetcher->getService)会调用createService函数, 来创建一个Service.
    其实这里调用的是这句
    return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
    我靠, 来看一看PolicyManager的makeNewLayoutInflater函数的实现吧:
    public static LayoutInflater makeNewLayoutInflater(Context context) {
        return sPolicy.makeNewLayoutInflater(context);
    }
    还记得这逻辑么?这会导致com.android.internal.policy.impl.Policy的makeNewLayoutInflater函数的调用, 定义如下:
        public LayoutInflater makeNewLayoutInflater(Context context) {
            return new PhoneLayoutInflater(context);
        }
        FUCK, 绕了这么大一圈, 最后还是会new一个PhoneLayoutInflater对象, 因此, 我们就知道了Window所拥有的其实是个PhoneLayoutInflater对象.


    第20行(ServiceFetcher->getService)会将刚创建的Service设置到cache中去.
   page6
在这篇文章里, 我们分析一下Window的setWindowManager函数的实现, 在这个函数里会为该Window创建一个WindowManager.
Window的setWindowManager函数的定义如下:
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     }
    第3行(Window->setWindowManager)会保存activity的token
    第4行(Window->setWindowManager)会保存appName
    第5-6行(Window->setWindowManager)判断是否需要硬件加速, 判断是否的条件是否用户显示启动该选项或者系统支持
    第7-9行(Window->setWindowManager)会通过mContext来获得WINDOW_SERVICE服务, 详细分析可以参考page7文件.
    第10行(Window->setWindowManager)会调用WindowManagerImpl的createLocalWindowManager函数来得到一个WindowManagerImpl对象, 并用该对象初始化成员变量mWindowManager.createLocalWindowManager函数的定义如下:
        public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
            return new WindowManagerImpl(mDisplay, parentWindow);
        }
    createLocalWindowManager函数只不过又创建了一个WindowManagerImpl对象, 只不过该对象有parentWindow而已.
page7
这里我们分析一下ContextImpl的WINDOW_SERVICE服务的获取过程, 而这是通过调用getSystemService函数来得到的,
getSystemService函数的实现逻辑其实我们已经分析过了, 其实最后会执行到这里:
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                 }});
        是不是很熟悉.
    第5-6行(ContextImpl->registerService)又通过调用getSystemService函数来获得DISPLAY_SERVICE服务, 别说了, 看下面的代码:
            registerService(DISPLAY_SERVICE, new ServiceFetcher() {
                    @Override
                    public Object createService(ContextImpl ctx) {
                        return new DisplayManager(ctx.getOuterContext());
                    }});
    会new一个DisplayManager, 关于DisplayManager的构造过程可以参考page8文件.
    第7行(ContextImpl->registerService)会调用DisplayManager的getDisplay函数, 关于getDisplay函数的详细分析可以参考page9文件.

第9行(ContextImpl->registerService)会用刚刚得到的Display对象new一个WindowManagerImpl, 并返回. WindowManagerImpl函数的构造函数如下所示:
    public WindowManagerImpl(Display display) {
this(display, null);
    }

    private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
    }
page8
这里我们看一下DisplayManager的构造过程, DisplayManager的构造函数如下:
1     public DisplayManager(Context context) {
    2         mContext = context;
    3         mGlobal = DisplayManagerGlobal.getInstance();
    4     }
    第2行(DisplayManager->DisplayManager)会保存Context
    第3行(DisplayManager->DisplayManager)会调用DisplayManagerGlobal.getInstance()函数来获得DisplayManagerGlobal实例, DisplayManagerGlobal的getInstance函数的定义如下:
    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     }
    从getInstance函数的定义可以知道, getInstance主要逻辑就是通过ServiceManager得到DISPLAY_SERVICE服务, 这是Binder相关的. 获得DISPLAY_SERVICE服务之后会用这个服务来创建一个DisplayManagerGlobal对象,
    DisplayManagerGlobal的构造函数的定义如下:
    private DisplayManagerGlobal(IDisplayManager dm) {
        mDm = dm;
    }




分享到:
评论

相关推荐

    理解Window和WindowManager

    Window是一个抽象类,具体实现是 PhoneWindow 。不管是 Activity 、 Dialog 、 Toast 它们的视图都是附加在Window上的,因此Window实际上是View的直接管理者。

    深入理解Android中的Window和WindowManager

    创建一个Window,需要通过WindowManager即可完成,WindowManager是外界访问Window的入口,Window具体实现位于WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC的过程。Android中,所有...

    在当前Activity之上创建悬浮view之WindowManager悬浮窗效果

    最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前Activity之上创建一个悬浮的view。 第一步:认识WindowManager 这个接口用于与 ...

    Android WindowManager悬浮显示歌词

    一个WindowManager悬浮窗,悬浮显示歌词效果。WindowManager背景设置为了透明色,显示的WindowManager关闭启动它的Activity回到主界面仍然有效。仅供参考............

    Android开发艺术探索.任玉刚(带详细书签).pdf

    8.3.1 Activity的Window创建过程 304 8.3.2 Dialog的Window创建过程 308 8.3.3 Toast的Window创建过程 311 第9章 四大组件的工作过程 316 9.1 四大组件的运行状态 316 9.2 Activity的工作过程 318 9.3 Service...

    Android开发艺术探索

     8.3.1 Activity的Window创建过程 / 304  8.3.2 Dialog的Window创建过程 / 308  8.3.3 Toast的Window创建过程 / 311  第9章 四大组件的工作过程 / 316  9.1 四大组件的运行状态 / 316  9.2 Activity的工作过程...

    WindowManagerService相关类图.eddx

    Activity,Window,DecorView,ViewRootImpl,WindowManager,WindowManagerImpl,WindowManagerGlobal,WindowManagerService相关类图

    Android编程设定activity进入和退出效果的方法

    设置Dialog首先通过getWindow()方法获取它的窗口,然后通过getAttributes()方法获得window的WindowManager.LayoutParams lp, lp有个公共属性windowAnimations, 只要把要实现的animation的id赋值给它就可以了。...

    Android代码-android-advanced-decode

    《Android进阶解密》源码 源码目录介绍 目录 简介 ...第1章介绍Android系统架构、系统源码目录和如何阅读源码,带领大家走进Android...第7章介绍WindowManager,包括WindowManager的关联类、Window的属性和Window

    Android 中 android.view.WindowLeaked的解决办法

    我们知道Android的每一个Activity都有个WindowManager窗体管理器,同样,构建在某个Activity之上的对话框、PopupWindow也有相应的WindowManager窗体管理器。因为对话框、PopupWindown不能脱离Activity而单独存在着,...

    android activity设置无标题实现全屏

    Activity设置全屏和无标题栏,要用到andorid.view.Window和Android.view.WindowManager。 Window.FEATURE_NO_TITLE表示无标题栏。 WindowManager.LayoutParams.FLAG_FULLSCREEN表示全屏。 具体用法如下: 1、设置...

    不依赖于Activity的Android全局悬浮窗的实现

    前言 当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可...通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。 每一个WindowManager对象

    通过案例分析Android WindowManager解析与骗取QQ密码的过程

    Windows Manager是一款窗口管理终端,可以远程连接到Linux的X桌面进行管理,...Window&&WindowManager介绍  分析demo之前,先要整理总结一下相关的知识。先看看Window类,Window是一个抽象类,位于代码树frameworks\u0

    android dialog与popwindow之间的简单运用

    注意:PopupWindow组件的使用问题,PopupWindow是一个阻塞对话框,如果你直接在Activity创建的方法中显示它,则会报错:android.view.WindowManager$BadTokenException:Unable to add window -- token null is not ...

    音乐播放器(J2ME)

    这种方法就可以在Activity运行过程中,动态地改变全屏与否。 六、音量调节: 音量调节的方法其实很简单,不过有人问到,我就在这里顺便说下: AudioManager am = (AudioManager) mContext.getSystemService...

    Android窗口机制

    每个Activity都有一个Window对象,这个对象是PhoneWindow类型的。 每个Window对象里面都维护着一个WindowManager对象。 Activity里面添加一个View是通过WindowManager的addView()方法实现的 相关关键类 ...

    Android利用WindowManager实现悬浮窗

    前言 你会发现QQ视频的时候,就算手机回到主页,视频小模块依旧能悬浮在桌面上。还有当年很火的各种手机... 应用Window:对应一个Activity 子Window:不能单独存在,它需要附属在特定的父Window中,比如常见的一些Dial

Global site tag (gtag.js) - Google Analytics