android 绘制过程分析,Android源码解析UI绘制流程

说到android的UI绘制流程,咱们首先介绍一下setContentView这个大家经常用到的方法。当创建一个Activity时,实现了onCreate方法,然后把创建好的布局Layout或者View通过调用setContentView(xxx)就显示到窗口中了。那么接下来就带着下面的疑问,了解View的加载过程。

为什么调用了setContentView后就可以显示出我们的局部页面?

看看源码中setContentView究竟做了什么

private Window mWindow;

public void setContentView(@LayoutRes int layoutResID) {

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

public Window getWindow() {

return mWindow;

}

从源码中可以看到setContentView中调用了getWindow方法获取了Window对象,看看源码中对Window对象的定义。

/**

* Abstract base class for a top-level window look and behavior policy. An

* instance of this class should be used as the top-level view added to the

* window manager. It provides standard UI policies such as a background, title

* area, default key processing, etc.

*

*

The only existing implementation of this abstract class is

* android.view.PhoneWindow, which you should instantiate when needing a

* Window.

*/

public abstract class Window {

public View findViewById(@IdRes int id) {}

public void setBackgroundDrawableResource(@DrawableRes int resId) {}

...

}

从注释中我们看到Window对象是一个顶层窗口的抽象类,里面封装了一些跟窗口UI相关的方法。既然Window是一个抽象类,那么我们就去看一下它的唯一实现类PhoneWindow。

public class PhoneWindow extends Window{

// This is the view in which the window contents are placed. It is either

// mDecor itself, or a child of mDecor where the contents go.

private ViewGroup mContentParent;

// This is the top-level view of the window, containing the window decor.

private DecorView mDecor;

@Override

public void setContentView(int layoutResID) {

// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window

// decor, when theme attributes and the like are crystalized. Do not check the feature

// before this happens.

if (mContentParent == null) {

installDecor();

} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

mContentParent.removeAllViews();

}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,

getContext());

transitionTo(newScene);

} else {

mLayoutInflater.inflate(layoutResID, mContentParent);

}

...

}

}

PhoneWindow类中的setContentView方法里面用到了mContentParent,它的类型是ViewGroup,从注释中看到我们的Activity中的View就会放到这个ViewGroup中,换而言之就是Window内容要摆放的一个地方,要么是mDecor自己要么就是mDecor的子类。而这个DecorView就是Window最顶层的View。从代码中看到当mContentParent为空时,调用了installDecor方法,进去看一下。

private void installDecor() {

if (mDecor == null) {

//generateDecor方法中new了一个DecorView

mDecor = generateDecor();

...

}

if (mContentParent == null) {

mContentParent = generateLayout(mDecor);

...

}

}

protected ViewGroup generateLayout(DecorView decor) {

...

// Inflate the window decor.

int layoutResource;

//根据不同的features加载不同的layout布局文件

int features = getLocalFeatures();

if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {

...

} else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {

...

} else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0

&& (features & (1 << FEATURE_ACTION_BAR)) == 0) {

...

} else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {

} else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {

...

} else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {

...

} else {

layoutResource = R.layout.screen_simple;

}

View in = mLayoutInflater.inflate(layoutResource, null);

decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));

mContentRoot = (ViewGroup) in;

//代码看到这就可以看出上文提到的mContentParent就是布局

//layoutResource中id为content的FrameLayout,下文中会接着提到。

//public static final int ID_ANDROID_CONTENT = com.android.internal.R.id.content;

ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);

return contentParent;

}

DecorView的结构拿最简单的R.layout.screen_simple为例,如下图:

83d727110f43bdf699d0a412a9141eb6.png

image.png

本文原创,转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值