众所周知,在Android中,界面是以Activity的形式存在的,但是,Activity类中还包含着一个Window对象
Window mWindow;
Q1. 那么,Activity和Window的关系是怎么样的呢?
A1. Activity并不负责视图控制,它只是控制生命周期和处理事件。真正控制视图的是Window
从Activity的启动说起
每个Activity都有唯一的类名,AMS中通过反射机制创建了Activity,并调用了Activity的attach函数
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader()
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent)
StrictMode.incrementExpectedActivityCount(activity.getClass())
r.intent.setExtrasClassLoader(cl)
r.intent.prepareToEnterProcess()
if (r.state != null) {
r.state.setClassLoader(cl)
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e)
}
}
在Activity中的attach()方法中,new了PhoneWindow实例
mWindow = new PhoneWindow(this)
梳理一下关系:
1)Activity中有一个Window类对象
2)Windows:抽象类,提供一组绘制接口
3)PhoneWindow:Windows的实现,实现了这些绘制接口
4)DecorView:PhoneWindow的一个内部类,Android视图的根结点(搭好的一个框架,xml往里填充内容, setContentView(R.layout.activity_main))
5)ViewRoot对应ViewRootImpl类,它是连接WindowManagerService和DecorView的纽带,View的三大流程(测量(measure),布局(layout),绘制(draw))均通过ViewRoot来完成。
ViewRoot并不属于View树的一份子。从源码实现上来看,它既非View的子类,也非View的父类,但是,它实现了ViewParent接口,这让它可以作为View的名义上的父视图。RootView继承了Handler类,可以接收事件并分发,Android的所有触屏事件、按键事件、界面刷新等事件都是通过ViewRoot进行分发的。
所有控件的基类都是View
Q2. LinearLayout和RelativeLayout哪个更高效
A2. LinearLayout只进行横向或者纵向的measure,因此measure的时间要比RelativeLayout短。但是,如果LinearLayout设置了weight属性,就有些不同了。如果使用weight属性,LinearLayout会避开设置过weight属性的view做一次measure,然后再对设置过weight属性的view做第二次measure。也就是说,设置了weight属性的LinearLayout的绘制效率比没有设置的要差。
总结一下上面分析的结论:
1.RelativeLayout会对子View进行两次measure,LinearLayout只对子View进行一次measure,而在设置了weight时,也会对weight进行两次measure,通常情况下,LinearLayout的性能要优于RelativeLayout。
2.在View的层级扁平,没有过多的嵌套的情况下,用LinearLayout效率更高,并且要尽量减少使用weight属性。
3.如果View的层级嵌套过多,则需要使用RelativeLayout来降低层级,因为Android是递归生成View的,过多的层级嵌套会严重影响View的绘制效率。
Q3. View是如何绘制出来的?
A3. 经过measure、layout、draw 三个过程绘制出来
1)measure,测量,match_parent,wrap_content,measure流程就从父容器传递到子元素中(xml中减少嵌套)
2)layout,布局,线性,网格,相对等
3)draw,绘制
* 1. Draw the background
* 2. If necessary, save the canvas’ layers to prepare for fading
* 3. Draw view’s content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
Q4. View和ViewGroup的关系
A4. ViewGroup也是继承View,这就意味着View本身可以是单个控件,也可以是多个控件组成的控件组。根据这个理论,Button显然是个View,而RelativeLayout不但是一个View还可以是一个ViewGroup,而ViewGroup内部是可以有子View的,这个子View同样也可能是ViewGroup,以此类推