DecorView 的创建
2024-08-30 20:41:43
在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 的,将在下篇文章中分析。
最新文章
- [No000091]SVN学习笔记2-TortoiseSVN Client初级操作update(获取)、commit(提交)
- reconnectingwebsocket.js
- TypeError: datetime.datetime(2016, 9, 25, 21, 12, 19, 135649) is not JSON serializable解决办法
- 启动 apache2.4 出现 invalid command order 问题 【由于 PHP 访问权限 403 问题引起】
- TensorFlow中max pooling层各参数的意义
- centos7 php7 安装composer时Failed to decode zlib stream解决办法
- IDOC、ALE、EDI三者之间的区别于联系
- C#-利用ZPL语言完毕条形码的生成和打印
- ubuntu下发布asp.net core并用nginx代理之旅
- Android ListView与RecycleView的对比使用
- [2017/5/28]FJ四校联考
- 用户注册之后,通过网易邮箱服务器(smtp.163.com)发送电子邮箱到注册者邮箱的的确认通知短信.(可根据需求自行调整)
- Excel 常用属性的一小部分
- Codeforces 1105B:Zuhair and Strings(字符串水题)
- idea 中dao层自动生成接口
- 洛谷 P2661信息传递
- ABAP 7.50 新特性之另一个CORRESPONDING
- 【C++】解决vs2015经常卡顿的办法
- js中的全局变量
- Spark笔记之数据本地性(data locality)
热门文章
- linux network name space
- 在ASP.NET Core 中使用Cookie中间件 (.net core 1.x适用)
- laravel有用的方法
- 【转】C++ 进程间的通讯(一):简单的有名管道实现
- Jafka源码分析——LogManager
- 内容可编辑且随内容自增长的div
- 【Dairy】2016.10.23 观火&;中彩记
- 【HDU2037】今年暑假不AC
- POJ3709 K-Anonymous Sequence 斜率优化DP
- vs code 快速生成vue 模板