Android应用开发之Activity的Window和WindowManager的创建过程(三)
白羽 2018-08-10 来源 :网络 阅读 1578 评论 0

摘要:本文将带你了解Android应用开发之Activity的Window和WindowManager的创建过程(三),希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之Activity的Window和WindowManager的创建过程(三),希望本文对大家学Android有所帮助


page9
 在这里我们分析一下DisplayManager的getDisplay函数的实现:
    1      public Display getDisplay(int displayId) {
    2             synchronized (mLock) {
    3                 return getOrCreateDisplayLocked(displayId, false /*assumeValid*/);
    4             }
    5      }
    第2行(DisplayManager->getDisplay)居然用一个锁, 不怕卡顿么?为什么要保护呢?
    第3行(DisplayManager->getDisplay)会调用getOrCreateDisplayLocked函数, getOrCreateDisplayLocked函数的定义如下:
    1     private Display getOrCreateDisplayLocked(int displayId, boolean assumeValid) {
    2         Display display = mDisplays.get(displayId);
    3         if (display == null) {
    4             display = mGlobal.getCompatibleDisplay(displayId,
    5                     mContext.getCompatibilityInfo(displayId));
    6             if (display != null) {
    7                 mDisplays.put(displayId, display);
    8             }
    9         } else if (!assumeValid && !display.isValid()) {
    10             display = null;
    11         }
    12         return display;
    13     }
    第2行(DisplayManager->getOrCreateDisplayLocked)会尝试在cache里获取.
    第4行(DisplayManager->getOrCreateDisplayLocked)会调用DisplayManagerGlobal的getCompatibleDisplay函数,
    其中传入的第二个参数通过调用ContextImpl的getCompatibilityInfo函数得到的, getCompatibilityInfo函数的定义如下:
        @Override
        public CompatibilityInfoHolder getCompatibilityInfo(int displayId) {
            return displayId == Display.DEFAULT_DISPLAY ? mPackageInfo.mCompatibilityInfo : null;
        }
    关于DisplayManagerGlobal的getCompatibleDisplay函数的详细分析可以参考page10文件.
    第12行(DisplayManager->getOrCreateDisplayLocked)返回该Display对象.
page10
 DisplayManagerGlobal的getCompatibleDisplay函数的定义如下:
 1     public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) {
    2         DisplayInfo displayInfo = getDisplayInfo(displayId);
    3         if (displayInfo == null) {
    4             return null;
    5         }
    6         return new Display(this, displayId, displayInfo, cih);
    7     }
    第2行(DisplayManagerGlobal->getCompatibleDisplay)会调用getDisplayInfo函数来获得当前显示设备的DisplayInfo.
    getDisplayInfo函数的定义如下:
        public DisplayInfo getDisplayInfo(int displayId) {
            try {
                synchronized (mLock) {
                    DisplayInfo info;
                    if (USE_CACHE) {
                        info = mDisplayInfoCache.get(displayId);
                        if (info != null) {
                            return info;
                        }
                    }

                    info = mDm.getDisplayInfo(displayId);
                    if (info == null) {
                        return null;
                    }

                    if (USE_CACHE) {
                        mDisplayInfoCache.put(displayId, info);
                    }
                    registerCallbackIfNeededLocked();

                    if (DEBUG) {
                        Log.d(TAG, "getDisplayInfo: displayId=" + displayId + ", info=" + info);
                    }
                    return info;
                }
            } catch (RemoteException ex) {
                Log.e(TAG, "Could not get display information from display manager.", ex);
                return null;
            }
        }
    getDisplayInfo函数的主要逻辑就是通过DisplayManager服务通过Binder来获得DisplayInfo信息, 并返回该DisplayInfo对象.

    第6行(DisplayManagerGlobal->getCompatibleDisplay)会用刚刚得到的DisplayInfo对象构造一个Display, 我们来看看Display的构造函数是如何定义的:
        public Display(DisplayManagerGlobal global,
                int displayId, DisplayInfo displayInfo /*not null*/,
                CompatibilityInfoHolder compatibilityInfo) {
            mGlobal = global;
            mDisplayId = displayId;
            mDisplayInfo = displayInfo;
            mCompatibilityInfo = compatibilityInfo;
            mIsValid = true;

            // Cache properties that cannot change as long as the display is valid.
            mLayerStack = displayInfo.layerStack;
            mFlags = displayInfo.flags;
            mType = displayInfo.type;
            mAddress = displayInfo.address;
        }
    构造函数除了初始化成员变量之外, 什么也没做啊.
page11
 这里我们分析一下PhoneWindow的setContainer函数的实现:
 public final void setContainer(Window container) {
         super.setContainer(container);
     }
    因为PhoneWindow继承自Window, 所以会调用Window的setContainer函数, Window的setContainer函数的定义如下:
        public void setContainer(Window container) {
            mContainer = container;
            if (container != null) {
                // Embedded screens never have a title.
                mFeatures |= 1<<FEATURE_NO_TITLE;
                mLocalFeatures |= 1<<FEATURE_NO_TITLE;
                container.mHasChildren = true;
            }
        }
    Window的setContainer函数的主要逻辑就是将container的mHasChildren设置为true    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程