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

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值