一、ANDROID应用ACTIVITY、DIALOG、POPWINDOW、TOAST窗口添加机制及源码分析

640?wx_fmt=png&wxfrom=5&wx_lazy=1

 浅析Window与WindowManager相关关系及源码

通过上面那幅图可以很直观的看见,Android屏幕显示的就是Window和各种View,Activity在其中的作用主要是管理生命周期、建 立窗口等。也就是说Window相关的东西对于Android屏幕来说是至关重要的(虽然前面分析Activity的setContentView等原理 时说过一点Window,但那只是皮毛。),所以有必要在分析Android应用Activity、Dialog、PopWindow加载显示机制前再看 看Window相关的一些东西。

2-1  Window与WindowManager基础关系

在分析Window与WindowManager之前我们先看一张图:

0?wx_fmt=png

接下来看一点代码,如下:

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。

0?wx_fmt=jpeg

本网站文章均为原创内容,并可随意转载,但请标明本文链接
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/一、android应用activity、dialog、popwindow、toast窗口添加机制及源码分析/

此条目发表在Android分类目录。将固定链接加入收藏夹。

发表评论

您的电子邮箱地址不会被公开。