浅析Window与WindowManager相关关系及源码
通过上面那幅图可以很直观的看见,Android屏幕显示的就是Window和各种View,Activity在其中的作用主要是管理生命周期、建 立窗口等。也就是说Window相关的东西对于Android屏幕来说是至关重要的(虽然前面分析Activity的setContentView等原理 时说过一点Window,但那只是皮毛。),所以有必要在分析Android应用Activity、Dialog、PopWindow加载显示机制前再看 看Window相关的一些东西。
2-1 Window与WindowManager基础关系
在分析Window与WindowManager之前我们先看一张图:
接下来看一点代码,如下:
1 2 3 4 5 6 7 8 9 | /** Interface to let you add and remove child views to an Activity. To get an instance * of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}. */ public interface ViewManager { public void addView(View view, ViewGroup.LayoutParams params); public void updateViewLayout(View view, ViewGroup.LayoutParams params); public void removeView(View view); } |
可以看见,ViewManager接口定义了一组规则,也就是add、update、remove的操作View接口。也就是说ViewManager是用来添加和移除activity中View的接口。继续往下看:
1 2 3 4 5 6 7 8 9 10 | public interface WindowManager extends ViewManager { ...... public Display getDefaultDisplay(); public void removeViewImmediate(View view); ...... public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable { ...... } } |
看见没有,WindowManager继承自ViewManager,然后自己还是一个接口,同时又定义了一个静态内部类LayoutParams(这个 类比较重要,后面会分析。提前透漏下,如果你在APP做过类似360助手屏幕的那个悬浮窗或者做过那种类似IOS的小白圆点,点击展开菜单功能,你或多或 少就能猜到这个类的重要性。)。WindowManager用来在应用与Window之间的接口、窗口顺序、消息等的管理。继续看下 ViewManager的另一个实现子类ViewGroup,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public abstract class ViewGroup extends View implements ViewParent, ViewManager { //protected ViewParent mParent; //这个成员是View定义的,ViewGroup继承自View,所以也可以拥有。 //这个变量就是前面我们一系列文章分析View向上传递的父节点,类似于一个链表Node的next一样 //最终指向了ViewRoot ...... public void addView(View child, LayoutParams params) { addView(child, -1, params); } ...... public void addView(View child, int index, LayoutParams params) { ...... // addViewInner() will call child.requestLayout() when setting the new LayoutParams // therefore, we call requestLayout() on ourselves before, so that the child's request // will be blocked at our level requestLayout(); invalidate( true ); addViewInner(child, index, params, false ); } ...... } |
这下理解上面那幅图了吧,所以说View通过ViewGroup的addView方法添加到ViewGroup中,而ViewGroup层层嵌套到最顶级都会显示在在一个窗口Window中(正如上面背景介绍中《Android应用setContentView与LayoutInflater加载解析机制源码分析》的示意图一样),其中每个View都有一个ViewParent类型的父节点mParent,最顶上的节点也是一个viewGroup,也即前面文章分析的Window的内部类DecorView(从《Android应用setContentView与LayoutInflater加载解析机制源码分析》的总结部分或者《Android应用层View绘制流程与源码分析》的5-1小节都可以验证这个结论)对象。同时通过上面背景中那幅图可以看出来,对于一个Activity只有一个DecorView(ViewRoot),也只有一个Window。
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/一、android应用activity、dialog、popwindow、toast窗口添加机制及源码分析/