activity显现页面流程
关于一个activity启动流程之前现已分析过,那么一个activity页面是怎么制作出来的呢?如下图:

主要流程总结:
- ActivityThread中启动了activity,会先调用activity的attach办法。
- attach办法中会实例化一个PhoneWindow目标,在PhoneWindow目标中会实例化一个DecorView。
- DecorView会依据Activty的主题配置,选择运用哪个系统的布局文件,然后运用layoutInflate来解析文件为view,提取出其间id为ID_ANDROID_CONTENT的控件,作为activity布局文件的父容器。
- ActivityThread中调用activity办法onCreate,咱们在onCreate中会调用setContentView来设置布局。
- setContentView中会运用layoutInflate来解析布局的xml文件为一个view目标,将view目标addView到DecorView的父容器中
- ActivityThread调用了activity的onResume办法,办法执行完成后,activity中会设置DecorView先为不可见,然后将该viewaddView到WMS中。
- addView时分,会先生成一个ViewRootImpl目标,保存DecorView目标,后续所有view刷新操作都由ViewRootImpl来办理。
- viewRootImpl会调用其内部办法requestlayout,来进行view的丈量,布局和制作等流程。
- WMS会和surfaceFlinger进行交互,开端制作界面显现给用户。
这个流程中,每个activity都会生成一个PhoneWindow目标,该目标完成了Window接口,一起每个PhoneWindow下都会有一个DecorView目标,该目标承继自帧布局。每个DecorView都会被包装到一个ViewRootImpl目标中。APP进程中,只会存在一个Windowmanager署理目标,即WindowManagerGlobal,内部会维护一个WMS署理类。
- 加载布局时分的参数attachRoot为true仍是false的差异:
- 假如为true,如下图代码,会将布局目标view刺进到root的布局中
- 假如为false,那么生成的view目标,只会运用root中的布局参数,但是不会对root有相关,不会刺进到root布局中
if (attachToRoot) {
root.addView(view, params);
} else {
view.setLayoutParams(params);
}
ViewRootImpl的requestlayout办法流程


- viewRootImpl的requestlayout办法会调用其内部目标DecorView的办法进行制作。
- 首要会调用其measure办法进行丈量。
- DecorView中会顺次调用其子布局的measure办法,别离核算出子布局的巨细,最终核算出自己的巨细
- 接着会调用DecorView的layout办法,核算其布局方位。
- 同比DecorView会顺次遍历其子布局的layout办法,核算出各自的方位
- 最终会调用draw办法,DecorView会调用自己的onDraw办法,接着会经过dispatchView告诉子布局调用其onDraw办法进行制作。
关于MeasureSpec:
- 组成
MeasureSpec是一个int值,但是其内部包含了两个信息,一个是size巨细,一个是size的形式,其间高两位是形式mode,低30位是size。 为啥要这样呢?
- 其实就是为了削减内存,每个view都需求两个MeasureSpec,然后一个activity有好多view,每个MeasureSpec都需求记载mode和size,经过这样放到一个int值中,能够削减内存
- 为了使得mode和size能够对应起来
- 关于MeasureSpec中的mode
- 关于布局xml中的设置的width,对应代码中是什么呢? xml中切当的数值宽度,代码中对应EXACTLY xml中的MATCH_PARENT,对应EXACTLY xml中的WRAP_CONTENT,对应AT_MOST xml中设置为0,对应UNSPECIFIED
- 测绘过程中,怎么承认子布局巨细的呢?(定寄父布局巨细为size,子布局为 childSize)
-
假如子布局是 大于0的详细数值, 那么子布局就会以childSize 作为宽高进行核算,形式为EXACTLY
-
假如子布局是 MATCH_PARENT
- 父布局是EXACTLY -> 子布局以size为准核算,形式为 EXACTLY
- 父布局是AT_MOST -> 子布局以size为准核算,形式为 AT_MOST
- 父布局是 UNSPECIFIED -> 子布局以size为准,形式为 UNSPECIFIED
-
假如子布局是 WRAP_CONTENT
- 父布局是 EXACTLY -> 子布局以size为准,形式为AT_MOST
- 父布局是 AT_MOST -> 子布局以size为准,形式为AT_MOST
- 父布局是 UNSPECIFIED -> 子布局以size为准,形式为 UNSPECIFIED
- 除此之外,其他情况都是 size为0,形式为UNSPECIFIED
一些问题
- 手机锁屏后,viewRootImplp还会发送屏障消息吗?
不会 手机锁屏,会触发activity的onStop办法,关于viewRootImpl的requestLayout办法,会判别假如activity处于stop状态,那么就不会持续往下走了,而发送屏障消息是在requestLayout中先发送的,所以答案是不会
- requestlayout 和 invalidate的差异 requestLayout是在用于从头制作整个view树,确认其巨细,布局最终进行制作。而 invalidate 只是用于从头调用当时view的onDraw办法,从头制作当时view
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。