Android中Activity、Window和View之间的关系

打开IDE创建一个Activity,IDE会自动生成一些代码,然后有一个空的Activity界面展示出来。这一过程包含了Activity  Window View之间的关系,在这个流程中,Activity是整个模型的控制单元,Window属于承载模型,负责承载视图,View是视图显示模型。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
     }   
    }

Activity的启动过程很复杂,最终是由ActivityThread中的performLaunchActivity()来完成的整个启动过程,在这个方法的内部会通过类加载器创建Activity的实例对象,并调用其attach方法为其关联运行过程中所依赖的一系列上下文环境变量。在Activty的attach方法里,系统会创建Activity所属的Window对象并且为其设置回调接口,Window对象的创建是通过PolicyManager的makeNewWindow方法实现的。由于Avtivity实现了Window的Callback接口,因此当Window接收到外界的状态改变就会回调到Activity的方法。

View是Android中的视图呈现方式,但是View不能单独存在,它必须附着在Window这个抽象的概念上,因此有试图就有Window。

Android中可以提供视图的地方有Activity  Dialog  Toast,还有一些依托Window实现的视图,如PopupWindow  Menu,它们也是视图,有视图就有Window,因此Activity  Dialog  Toast等都对应一个Window

那么Window和View之间的纽带呢:ViewRoot

ViewRoot对应于ViewRootImpl类,它是连接WindowManager和Decorview的纽带,View的三大流程(measure, layout, draw)均是通过ViewRoot来完成的。在ActivityThread 中,当Activity对象被创建完后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象和DecorView建立关联。

root=new ViewRootImpl(view.getContext),display);
root.setView(view,wparams,panelParentView);
View的绘制流程从ViewRoot的performTraversals方法开始,经过measure, layout和draw三个过程最终将View绘制出来,其中measure用来测量View的宽高,layout用来确定View在父容器中的放置位置,draw负责将View绘制在屏幕上。如此反复完成一棵View树的遍历,整个View视图就显示在屏幕上了。


在onCreat()中,我们只有一个setContentView()的操作,在Activity的setContentView的实现可以看出,Activity将具体实现交给了Window处理,而Window的具体实现是PhoneWindow在setContent中创建了DecorView,DecorView是整棵View树的顶级View,然后将View添加到DecorView的mContentParent中,最后回调Activity的onContntChanges方法通知Activity视图已经发生改变。


DecorView作为顶级View,一般情况下它内部会包含一个竖直方向的LinearLayout,在这个LinearLayout里面有上下两个部分,上面是标题栏,下面是内容栏,其中标题栏一般由Activity的Theme样式所决定。在Activity中我们通过setContentView所设置的布局文件其实就是被加到内容栏之中的。


一个比喻总结下Activity Window View三只之间的关系:Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)。

Activity在onCreate之前调用attach方法,在attach方法中会创建window对象。window对象创建时并木有创建Decor对象对象。用户在Activity中调用setContentView,然后调用window的setContentView,这时会检查DecorView是否存在,如果不存在则创建DecorView对象,然后把用户自己的View 添加到DecorView中。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值