Activity与Window、PhoneWindow、DecorView之间的关系是什么
Activity是什么? activity是Android中的四大组件之一,其负责数据模型和页面模型的交互以表达业务逻辑显示能力等 那么Window又是什么呢? Window是一个抽象类,一个Activity维护了一个Window,而window只有一个唯一的子类实现-->PhoneWindow 所以一个Activity中维护了一个PhoneWindow实例 PhoneWindow是什么,怎么创建的 ActivityThread中handleLaunchActivity-->performLaunchActivity-->创建Activity,创建Application(makeApplication),Context,接着对activity进行了attach-->里面创建了mWindow = PhoneWindow()--≥mInstrumentation#callActivityCreate()
Activity执行oncreate()-->setContentView(resId)后执行了mWindow.setContentView()
这里的mWindoW就是mPhoneWindow,mPhoneWindow里面有一个成员变量mDecorView,mPhoneWindow的作用是分装了DecorView对子view的再次包装,解耦UI的逻辑操作,创建mDecorView和mContentParent的生成 DecorView mDecorView会通过feature_no_title等配置不同的子容器 generateLayout()-->解析resId的xml把view通过addview添加到decorview上 最终会通过mInflate.inflate(resid,mContentParent)添加到mContentParent上 这个时候oncreate就执行完了
Activity怎么显示的
当执行到handleResumeActivity时,activity的onResume被调用,接着会通过r.activity.getDecorView()获取decorView对象,通过WindowManager.addview把decorView添加进去-->最终会通过WindowManagerGlobal.addView()
WindowManagerGlobal.addView接着创建了ViewRootImpl()-->setView()
ViewRoot是什么
ViewRoot是一个抽象类,它的实现类是ViewRootImpl,负责连接WMS和DecorView的交互通讯,实际上是双向绑定事件,而这个事件是binder驱动的,服务端通过IWindow向decorview派发事件,完成View的绘制都是在ViewRootImpl里
setView里执行了resquestLayout()-->scheduleTraversals()--> mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal();
}
}
void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
if (mProfile) {
Debug.startMethodTracing("ViewAncestor");
}
performTraversals();
if (mProfile) {
Debug.stopMethodTracing();
mProfile = false;
}
}
}
private void performTraversals() {
.......
.......
relayout addtoDiaplay()
.......
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
......
// Ask host how big it wants to be
//Measure
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
......
//layout
performLayout(lp, mWidth, mHeight);
......
//Draw
performDraw();
}
relayout里有mWindowSession.addtoDiaplay(mWindow) Session负责WMS的通讯,里面有一个suface,维护suface层级,View的宽度等
//从根节点向下遍历View树,完成所有ViewGroup和View的测量工作,计算出所有ViewGroup和View显示出来需要的高度和宽度;
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
if (mView == null) {
return;
}
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
try {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
//从根节点向下遍历View树,完成所有ViewGroup和View的布局计算工作,根据测量出来的宽高及自身属性,计算出所有ViewGroup和View显示在屏幕上的区域;
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
......
try {
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
......
}
......
}
//从根节点向下遍历View树,完成所有ViewGroup和View的绘制工作,根据布局过程计算出的显示区域,将所有View的当前需显示的内容画到屏幕上
private void performDraw() {
......
try {
draw(fullRedrawNeeded);
} finally {
mIsDrawing = false;
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
.......
.......
.......
}