DecorView 的创建

在Activity 的启动过程中,调用ActivityThread 的handleResumeActivity 方法时,先得到一个与Activity 关联的PhoneWindow 对象,然后通过PhoneWindow 来获取DecorView。

PhoneWindow.java

public final View getDecorView() {
  if (mDecor == null) {
    installDecor();
  }
  return mDecor;            
}

private void installDecor() {
  if (mDecor == null) {
    // 生成DecorView
    mDecor = generateDecor();
    mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
    mDecor.setIsRootNamespace(true);
  }
  if (mContentParent == null) {
    // 根据Window 样式确定DecorView 中的布局内容,mContentParent 就是DecorView 的第一个子View,也是我们写的Activity onCreate()中setContentView() 的父View
    mContentParent = generateLayout(mDecor);
    final DecorContentParent decorContentParent = (DecorContentParent)        mDecor.findViewById(R.id.decor_content_parent);
  }
  ...
}

 

DecorView 是PhoneWindow 的一个内部类,继承FrameLayout,generateDecor() 也是像平时我们自定义View 是new 一个DecorView,只不过多了一个featureId 参数,该参数如果是-1,表示这个View 是一个DecorView

protected DecorView generateDecor() {
  return new DecorView(getContext(), -1);
}

private final class DecorView extends FrameLayout {
  public DecorView(Context context, int featureId) {
    super(context);
    mFeatureId = featureId;
  }
}

 

 因此,DecorView 中的布局是怎样的,主要是由generateLayout(mDecor) 决定的

protected ViewGroup generateLayout(DecorView decor) {
  // 获取Window 的样式
  TypedArray a = getWindowStyle();
   ...
  final WindowManager windowService = (WindowManager) getContext().getSysteService(Context.WINDOW_SERVICE);
  if (windowService != null) {
    final Display display = windowService.getDefaultDisplay();
    ...  
  }
  final Context context = getContext();
  final int targetSdk = context.getApplicationInfo().targetSdkVersion();
  ...
  WindowManager.LayoutParams params = getAttributes();
  // Inflate the window decor
  int layoutResource;
  int features = getLocalFeatures();
  if (){
    // 判读features 中是否包含FEATURE_SWIPE_TO_DISMISS
    
  } else if() {
    // 如果features 包含自定义的Title
    layoutResource = R.layout.screen_custom_title;
  } else {
    // 如果window 属性没有任何装饰(没有TitleBar,没有ActionBar 等)
    layoutResource = R.layout.screen_simple;
  }
  mDecor.startChanging();
  // 可以看到DecorView 也是通过inflate 加载布局的,系统framework 默认的布局资源位于frameworks\base\core\res\res\layout 目录下
  View in = mLayoutInflater.inflate(layoutResource, null);
  decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
  mContentRoot = (ViewGroup) in;
  ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
  if (contentParent == null) {  
    // 抛出异常
  }
  ...
  mDecor.finishChanging();
  return contentParent;
}

 

由此得出,DecorView 是根据不同的window 属性通过inflate() 方法加载位于frameworks\base\core\res\res\layout 目录下对应的布局资源生成的。至于LayoutInflate.inflate() 方法是如何加载布局文件并解析生成View 的,将在下篇文章中分析。

转载于:https://www.cnblogs.com/leekx/p/7812060.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值