博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WindowManager解析
阅读量:6162 次
发布时间:2019-06-21

本文共 3525 字,大约阅读时间需要 11 分钟。

hot3.png

Window 与 WindowManager 之间使用的是桥接模式,先来看看他们的 uml 图: 输入图片说明   这里写图片描述 Window 类和 PhoneWindow 类为抽象部分,PhoneWindow 为 Window 类的唯一实现子类,在 Window 类中,持有了一个 WindowManager 类的引用,并且在 setWindowManager 方法中将其赋值为了 WindowManagerImpl 对象:

public void setWindowManager(WindowManager wm, IBinder appToken, String appName,        boolean hardwareAccelerated) {    ...    mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);}

对应着的 WindowManager 接口和 WindowManagerImpl 类就组成了实现部分,所以说这四个类使用的就是典型的桥接模式,Window 中的 addView,removeView 等操作都桥接给了 WindowManagerImpl 去处理。但是实际上 WindowManagerImpl 中并没有去实现 addView 方法,在 WindowManagerImpl 类中持有了一个 WindowManagerGlobal 对象的引用,这个引用是通过单例模式获取的,而 addView 等方法就直接交给了 WindowManagerGlobal 类去处理:

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {    applyDefaultToken(params);    mGlobal.addView(view, params, mDisplay, mParentWindow);}

继续分析 WindowManagerGlobal 类的 addView 函数,在该函数中,最后调用到了 ViewRootImpl 类中的 setView 成员方法,ViewRootImpl 类中的 setView 方法最后会调用到 scheduleTraversals 方法,scheduleTraversals 方法:

void scheduleTraversals() {    if (!mTraversalScheduled) {        ...        notifyRendererOfFramePending();        pokeDrawLockIfNeeded();    }}

我们继续看看 pokeDrawLockIfNeeded 函数:

void pokeDrawLockIfNeeded() {    final int displayState = mAttachInfo.mDisplayState;    if (mView != null && mAdded && mTraversalScheduled            && (displayState == Display.STATE_DOZE                    || displayState == Display.STATE_DOZE_SUSPEND)) {        try {            mWindowSession.pokeDrawLock(mWindow);        } catch (RemoteException ex) {            // System server died, oh well.        }    }}

看到了 mWindowSession 对象,是不是很熟悉,mWindowSession 对象的创建:

mWindowSession = WindowManagerGlobal.getWindowSession();

嗯,又回到了 WindowManagerGlobal 类,去看看它的 getWindowSession 方法:

public static IWindowSession getWindowSession() {    synchronized (WindowManagerGlobal.class) {        if (sWindowSession == null) {            try {                InputMethodManager imm = InputMethodManager.getInstance();                IWindowManager windowManager = getWindowManagerService();                sWindowSession = windowManager.openSession(                        new IWindowSessionCallback.Stub() {                            @Override                            public void onAnimatorScaleChanged(float scale) {                                ValueAnimator.setDurationScale(scale);                            }                        },                        imm.getClient(), imm.getInputContext());            } catch (RemoteException e) {                Log.e(TAG, "Failed to open window session", e);            }        }        return sWindowSession;    }}

WindowSession 是通过 IWindowManager 创建的:

public static IWindowManager getWindowManagerService() {    synchronized (WindowManagerGlobal.class) {        if (sWindowManagerService == null) {            sWindowManagerService = IWindowManager.Stub.asInterface(                    ServiceManager.getService("window"));            try {                sWindowManagerService = getWindowManagerService();                ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());            } catch (RemoteException e) {                Log.e(TAG, "Failed to get WindowManagerService, cannot set animator scale", e);            }        }        return sWindowManagerService;    }}

跨进程之间的通信,最终调用到的是 WindowManagerService 中。这里需要简单提到的一句是 WMS 和 AMS 一样都是由 SystemServer 启动的,是在另一个进程中的,这也是为什么需要跨进程之间的通信。

转载于:https://my.oschina.net/leonardtang/blog/779045

你可能感兴趣的文章
Bootstrap table分页问题汇总
查看>>
javascript进阶课程--第三章--匿名函数和闭包
查看>>
多线程UI
查看>>
Jenkins部署java项目实例
查看>>
深入理解Python中的yield和send
查看>>
好玩的WPF第四弹:用Viewport2DVisual3D实现3D旋转效果
查看>>
javascript学习笔记
查看>>
VLFeat-----mean sift开源库【配置】【转载】
查看>>
wa,架构师
查看>>
文件打包,下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件
查看>>
Ioc容器应用浅析
查看>>
把孩子打造成为码农
查看>>
Kinect+OpenNI学习笔记之2(获取kinect的颜色图像和深度图像)
查看>>
Microsoft Web Platform Installer 5.0
查看>>
ubuntu vnc安装
查看>>
LVS+Redis部署手册
查看>>
搜索服务Elasticsearch与Solr比较
查看>>
CKEditor的使用方法
查看>>
JavaScript:综合案例---房贷计算器的实现
查看>>
【SpringMVC学习05】SpringMVC中的参数绑定总结——较乱后期准备加入 同一篇幅他人的参数绑定...
查看>>