为什么要分析类图?
WMS是一个复杂的模块,就像一个很大的家族,里面有各种角色,认识类图就像是认识WMS模块中的各个角色,不先把人认清楚了,怎么更好的理解他们之间的交互?
我觉得,这也是面向对象的语言魅力,面向对象的语言构建了一个小小的世界,每一个类都是其中的一个角色。
首先插一张类图,方便后面的分析
具体类图小析
ConfigurationContainer
类属性分析
这是WMS模块中的始祖级别的类,WMS中所有的类都继承于它。
ConfigurationContainer类中主要有三个Configuration对象,Configuration 本事就是各种基础参数 mode的记录
mRequestedOverrideConfiguration:当前应用主动请求的Configuration
mResolvedOverrideConfiguration:mRequestedOverrideConfiguration 经过子类的的调整后的对应容器请求的config,子类会重现相关的方法。
mFullConfiguration:当前使用的Configuration。
public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
//下面三个Configuration对象是配置相关的基础对象,onfiguration对象本身主要是一些参数的配置。
/**
* Contains requested override configuration settings applied to this configuration container. 当前应用主动请求的所有config
*/
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.为mRequestedOverrideConfiguration 经过子类的的调整后的对应容器请求的config
*/
private Configuration mResolvedOverrideConfiguration = new Configuration();
/**
* Contains full configuration applied to this configuration container. Corresponds to full
* parent's config with applied {@link #mResolvedOverrideConfiguration}.为父亲的config(mFullConfiguration) 加上自己的mResolvedOverrideConfiguration 组合成自身的mResolvedOverrideConfiguration
*/
private Configuration mFullConfiguration = new Configuration();//这个是返回的configuration
/**
* Returns full configuration applied to this configuration container.
* This method should be used for getting settings applied in each particular level of the
* hierarchy.从getConfiguration函数中可以看出,mFullConfiguration是在使用的congfiguration
*/
public Configuration getConfiguration() {
return mFullConfiguration;
}
//onConfigurationChanged 当配置发生改变时调用,会在onParentChanged中调用
public void onConfigurationChanged(Configuration newParentConfig) {
mResolvedTmpConfig.setTo(mResolvedOverrideConfiguration); //先保存mResolvedOverrideConfiguration
resolveOverrideConfiguration(newParentConfig);//mResolvedOverrideConfiguration从newParentConfig中算出来
mFullConfiguration.setTo(newParentConfig);//mFullConfiguration 设为 newParentConfig
mFullConfiguration.updateFrom(mResolvedOverrideConfiguration);//重新计算mFullConfiguration
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);
}
}
//应该是parent发生变化是被调用
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
// Removing parent usually means that we've detached this entity to destroy it or to attach
// to another parent. In both cases we don't need to update the configuration now.
if (newParent != null) {
// Update full configuration of this container and all its children.
onConfigurationChanged(newParent.mFullConfiguration);
// Update merged override configuration of this container and all its children.
onMergedOverrideConfigurationChanged();
}
}
}
WindowContainer
也是一个子孙很多的类(当前WMS模块的类都是其子类),本身也是一个模板类,模板参数是继承于自己的子类。(这种类真的很绕,因为androd framework层面的有很多类树结构的设计,这种设计便于遍历,从而就需要这种模板类)。
类属性分析
持有DisplayContent、SurfaceControl、SurfaceFreezer对象,以及最重要的WindowManagerService对象,这些对象放在这个类,说明这些对象是每一个WMS模块类都需要的。
/**
* Defines common functionality for classes that can hold windows directly or through their 定义了很多公用函数,可以直接用来管理窗口。
* children in a hierarchy form.
* The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime
* changes are made to this class.
*/
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable {
/**
* The parent of this window container.
* For removing or setting new parent {@link #setParent} should be used, because it also // 保存父节点
* performs configuration updates based on new parent's settings.
*/
private WindowContainer<WindowContainer> mParent = null;
// List of children for this window container. List is in z-order as the children appear on
// screen with the top-most window container at the tail of the list.
// 存储子节点WindowContainer的list
protected final WindowList<E> mChildren = new WindowList<E>();
// The display this window container is on.
//每一个window 都需要在一个display之上
protected DisplayContent mDisplayContent;
//窗口的内容是绘制在surface上的,SurfaceControl是java层和native层设置surface相关的唯一渠道,所有的surface参数都需要调用SurfaceControl来设置。
protected SurfaceControl mSurfaceControl;
/**
* Windows that clients are waiting to have drawn. 需要等待绘制的窗口List
*/
final ArrayList<WindowState> mWaitingForDrawn = new ArrayList<>();
//动效控制对象
protected final SurfaceAnimator mSurfaceAnimator;
//冻结管理类
final SurfaceFreezer mSurfaceFreezer;
//窗口管理服务对象,WMS的核心管家,虽然不在WMS类图中。就像一个专业的CEO吧,管理大家族公司WindowManagerService值得单独分析
protected final WindowManagerService mWmService;
//留下一个监听用的类
private final List<WindowContainerListener> mListeners = new ArrayList<>();
//配置变换了,要把父节点的配置都改变一下
public void onConfigurationChanged(Configuration newParentConfig) {
super.onConfigurationChanged(newParentConfig);
updateSurfacePositionNonOrganized();
scheduleAnimation();
}
void reparent(WindowContainer newParent, int position) {
...
final WindowContainer oldParent = mParent;
...
// The display object before reparenting as that might lead to old parent getting removed
// from the display if it no longer has any child.
final DisplayContent prevDc