Activity的层级结构

要想优化activity的布局首先应该清楚activity的布局层次。
Activity包含一个phonewindow,phonewindow里面有一个内部类就是DecorView,Decorview是一个FrameLayout,里面包括两个子view,一个是LinearLayout(标题栏加内容),另外一个是底部状态栏。
在这里插入图片描述
当Activity启动的时候会通过AMS的ApplictionThreadProxy将创建的消息通过binder驱动发送到应用进程的ApplicationThread中,然后通过handler消息机制将创建Activity的消息发送到主线程中,并调用创建activity的handleLancheActivity方法,通过反射生成Activity对象。
这里主要有两个方面,一个是onCreate方法和onResume方法。

onCreate方法
在调用onCreate之前会创建调用attach方法,创建一个phoneWindow对象。
这里主要讲一下onCreate方法里面的setContentView方法,setContentView其实是调用phoneWindow的setContentView方法。
首先会判断mContentParent的布局是不是null,如果是空则会接着判断decor是不是null,如果decorView也是null,则调用decorview的构造方法,并将自己添加到phonewindow里面,如果不为空则直接添加到phonewindow里面。接着用生成的decorView,去生成mContentParent布局对象,在生成content布局对象的时候也会生成一些decorview的相关对象,例如是否全屏,为解析在style里面设置的属性,例如背景等。

onResume
在onResume方法之后才会真正开始进行绘制和展示绘制的内容,先看一下handleResumeActivity方法

 @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
            // 回调Activity的onResume方法
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        if (r.window == null && !a.mFinished && willBeVisible) {
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    //调用WindowManagerImpl的addView方法
                    wm.addView(decor, l);
                } else {
                    a.onWindowAttributesChanged(l);
                }
            }
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }
    }

可以看到先回调Activity的onResume方法,之后就会调用WindowManagerImpl的addView方法,最终会调用WindowManagerGlobal的addView,在WindowManagerGlobal里面创建一个ViewRootImpl对象,并调用这个对象的setView把DecorView和ViewRootImpl对象绑定起来。在DecorView的setView主要做了三件事:
第一件:requestLayout刷新布局的操作。
第二件:调用mWindowSession的addToDisplay将Window的添加的工作交给系统WMS来实现。
第三件:对输入事件的处理。

首先分析刷新屏幕布局。

private void performTraversals() {
	 // 1、relayoutWindow 方法是将mSurface跟WMS关联
	relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
	performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
	performLayout(lp, mWidth, mHeight);
	performDraw();
}

在绘制的时候需要一个Canvas作为画布,而这个canvas画布则是通过mSurface.lockCanvas获取到。

第二件事:调用mWindowSession.addToDisplay将window的添加工作交给WMS里面,通过WMS来添加window,添加成功则直接将绘制的数据显示在屏幕上。

第三件事:设置以一系列的输入通道。
当硬件驱动发起事件,底层会进行一系列处理,最终会调用InputDispath,会将输入事件分发到需要的地方,例如WindowInputEventReceiver中,最终会调用ViewPostImeInputStage的onPrecess方法,最终调用dispatchPointerEvent,最终会调用DecorView的disPathTouchEvent。调用顺序---->DecorView---->Activity---->PhoneWindow---->DecorView---->ViewGroup。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值