窗口容器的Configuration介绍

窗口容器的Configuration介绍

这个问题也困扰我很久!很多configer 我一直也没管它,只是有时候遇到了 糊里糊涂的!!!

不过遇到一个MTBF set config重启问题 还是理了下,这里记录一下

先理一下到底是怎么回事吧

首先看看到底有哪些config吧

我们说WindowManager 大都结构都称之为容器的东西 这个容器的基类是ConfigurationContainer,这玩意本身是容器 同时他也是容器的容器!绕口燃石就是这个意思

所有的容器(不管是Task 还是activityRecord等)都继承于他

乱七八糟的各种config 实际上整理一下也就下面几个(我们之所以觉得多 是因为不清楚,清楚了其实也就不复杂了)

/**

  • Contains requested override configuration settings applied to this configuration container.
    */
    private Configuration mRequestedOverrideConfiguration = new Configuration();

/**

  • Contains the requested override configuration with parent and policy constraints applied.
  • This is the set of overrides that gets applied to the full and merged configurations.
    */
    private Configuration mResolvedOverrideConfiguration = new Configuration();

/**

  • Contains full configuration applied to this configuration container. Corresponds to full
  • parent’s config with applied {@link #mResolvedOverrideConfiguration}.
    */
    private Configuration mFullConfiguration = new Configuration();

/**

  • Contains merged override configuration settings from the top of the hierarchy down to this
  • particular instance. It is different from {@link #mFullConfiguration} because it starts from
  • topmost container’s override config instead of global config.
    */
    private Configuration mMergedOverrideConfiguration = new Configuration();

这几个config到底是什么意思呢?

首先看第一个mRequestedOverrideConfiguration

这个里面其实就是当前ConfigurationContainer 主动请求的所有config ,以nightmode 为例说明

app可以自己调用 setOverrideNightMode

public boolean setOverrideNightMode(int nightMode) {
final int currentUiMode = mRequestedOverrideConfiguration.uiMode;
final int currentNightMode = currentUiMode & Configuration.UI_MODE_NIGHT_MASK;
final int validNightMode = nightMode & Configuration.UI_MODE_NIGHT_MASK;
if (currentNightMode == validNightMode) {
return false;
}
mRequestsTmpConfig.setTo(getRequestedOverrideConfiguration());
mRequestsTmpConfig.uiMode = validNightMode
| (currentUiMode & ~Configuration.UI_MODE_NIGHT_MASK);
onRequestedOverrideConfigurationChanged(mRequestsTmpConfig);
return true;
}

来改变自身NightMode 从而使应用和系统默认应用到所有app 不一样 可以理解为此为当前应用主动请求的所有config

mResolvedOverrideConfiguration 是个啥?

来看看mResolvedOverrideConfiguration的计算

默认mResolvedOverrideConfiguration 其实就等于mRequestedOverrideConfiguration

void resolveOverrideConfiguration(Configuration newParentConfig) {
mResolvedOverrideConfiguration.setTo(mRequestedOverrideConfiguration);
}
然后对于后面的子类 大都会重写一下resolveOverrideConfiguration
如:

DisplayArea.java
void resolveOverrideConfiguration(Configuration newParentConfiguration) {
super.resolveOverrideConfiguration(newParentConfiguration);
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
final Rect overrideBounds = resolvedConfig.windowConfiguration.getBounds();
final Rect overrideAppBounds = resolvedConfig.windowConfiguration.getAppBounds();
final Rect parentAppBounds = newParentConfiguration.windowConfiguration.getAppBounds();

// If there is no override of appBounds, restrict appBounds to the override bounds.
if (!overrideBounds.isEmpty() && (overrideAppBounds == null || overrideAppBounds.isEmpty())
&& parentAppBounds != null && !parentAppBounds.isEmpty()) {
final Rect appBounds = new Rect(overrideBounds);
appBounds.intersect(parentAppBounds);
resolvedConfig.windowConfiguration.setAppBounds(appBounds);
}
}

会对mResolvedOverrideConfiguration的AppBounds根据自身规则进行调整一下

所以可以理解为mResolvedOverrideConfiguration 为mRequestedOverrideConfiguration 经过子类的的调整后的对应容器请求的config

mFullConfiguration 又是什么呢 还是看看怎么计算的

public void onConfigurationChanged(Configuration newParentConfig) {
mResolvedTmpConfig.setTo(mResolvedOverrideConfiguration);
resolveOverrideConfiguration(newParentConfig);
mFullConfiguration.setTo(newParentConfig);
mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);
onMergedOverrideConfigurationChanged();
if (!mResolvedTmpConfig.equals(mResolvedOverrideConfiguration)) {
// This depends on the assumption that change-listeners don’t do
// their own override resolution. This way, dependent hierarchies
// can stay properly synced-up with a primary hierarchy’s constraints.
// Since the hierarchies will be merged, this whole thing will go away
// before the assumption will be broken.
// Inform listeners of the change.
for (int i = mChangeListeners.size() - 1; i >= 0; --i) {
mChangeListeners.get(i).onRequestedOverrideConfigurationChanged(
mResolvedOverrideConfiguration);
}
}
for (int i = mChangeListeners.size() - 1; i >= 0; --i) {
mChangeListeners.get(i).onMergedOverrideConfigurationChanged(
mMergedOverrideConfiguration);
}
for (int i = getChildCount() - 1; i >= 0; --i) {
dispatchConfigurationToChild(getChildAt(i), mFullConfiguration);
}
}

mFullConfiguration.setTo(newParentConfig);
mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);

newParentConfig 为 传进来的一个congfig 首先将mFullConfiguration 设置为传进来的mFullConfiguration

然后再用mResolvedOverrideConfiguration 去更新mFullConfiguration

这是什么意思 就是首先设置成传进来的config 然后再结合mResolvedOverrideConfiguration 就是自身调整的config 组成自己的mFullConfiguration

那newParentConfig 其实就是自己父亲的mFullConfiguration 如果没有父亲就是null

为什么这么说 我们看一般怎么调用的onConfigurationChanged

onConfigurationChanged(parent != null ? parent.getConfiguration() : Configuration.EMPTY);

到此就清楚了 mFullConfiguration 即为父亲的config(mFullConfiguration) 加上自己的mResolvedOverrideConfiguration 组合成自身的mResolvedOverrideConfiguration

是不是这个onConfigurationChanged 叫onParentConfigurationChanged 更合适呢? 我反正很疑惑为什么叫onConfigurationChanged

然后默认我们最终用的也就是mFullConfiguration

/**

  • Returns full configuration applied to this configuration container.
  • This method should be used for getting settings applied in each particular level of the
  • hierarchy.
    */
    public Configuration getConfiguration() {
    return mFullConfiguration;
    }

但是像 WindowState 子容器 还会重写自己的getConfiguration 。

@Override
public Configuration getConfiguration() {
// If the process has not registered to any display area to listen to the configuration
// change, we can simply return the mFullConfiguration as default.
if (!registeredForDisplayAreaConfigChanges()) {
return super.getConfiguration();
}

// We use the process config this window is associated with as the based global config since
// the process can override its config, but isn't part of the window hierarchy.
mTempConfiguration.setTo(getProcessGlobalConfiguration());
mTempConfiguration.updateFrom(getMergedOverrideConfiguration());
return mTempConfiguration;

}
之所以widowstate会重写 我觉得应该是因为 悬浮窗类似这样的窗口

至于getProcessGlobalConfiguration 这个config就不在这里说了

对于窗口就是getMergedOverrideConfiguration 去更新当前ProcessGlobalConfiguration

那mMergedOverrideConfiguration 又是啥呢?

void onMergedOverrideConfigurationChanged() {
final ConfigurationContainer parent = getParent();
if (parent != null) {
mMergedOverrideConfiguration.setTo(parent.getMergedOverrideConfiguration());
mMergedOverrideConfiguration.updateFrom(mResolvedOverrideConfiguration);
} else {
mMergedOverrideConfiguration.setTo(mResolvedOverrideConfiguration);
}
for (int i = getChildCount() - 1; i >= 0; --i) {
final ConfigurationContainer child = getChildAt(i);
child.onMergedOverrideConfigurationChanged();
}
}

很明显其就是自父节点到自身的所有请求的ResolvedOverrideConfiguration的和(当然这里说的和不是很准确 应该说是取并集且子类的覆盖父类的一个并)

没有父亲节点就是mResolvedOverrideConfiguration

到此就说完了

到这里是不是还有个以为mMergedOverrideConfiguration 和mFullConfiguration 有区别么?

大家觉得有区别么?

咋一看不都是当没有父亲的都是都是null 或者说empty么?

那差异哪来的呢 其实来源于DisplayContent

DisplayContent 的mFullConfiguration 和 mResolvedOverrideConfiguration 初始化就不一样 DisplayContent会主动更新mFullConfiguration

但这个更新不会去更新mResolvedOverrideConfiguration

(至于getProcessGlobalConfiguration 大致是使用的top 以及app请求的config 没细看 )

总的来说就是mRequestedOverrideConfiguration 记录当前容器主动请求的所有变更 mResolvedOverrideConfiguration 是各个子容器对mRequestedOverrideConfiguration的策略调整

mMergedOverrideConfiguration 是所有主动求情的变化即可(自父而下的累加 子请求等级高于父亲请求等级)

mFullConfiguration 就为当前容器的config

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值