-
viewrootimpl,windowmanager等的关系。
-
view绘制流程
子线程为什么不能更新ui?
ViewRootImpl.java
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
//在主线程触发,ActiviyThread.handleResumeActivity()-->wm.addView(decor, l);
public ViewRootImpl(Context context, Display display) {
mThread = Thread.currentThread();
}
- 什么时候获取宽高?为什么?
//1. ViewTreeObserver.dispatchOnGlobalLayout
ViewRootImpl.java
private void performTraversals() {
//host代表view DecorView
host.dispatchAttachedToWindow(mAttachInfo, 0);
//触发dispatchOnWindowAttachedChange回掉
mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true);
//host代表view DecorView
host.dispatchWindowVisibilityChanged(viewVisibility);
//测量确定window大小
measureHierarchy()
//调整window大小
relayoutWindow()
//测量
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
//摆放
performLayout(lp, mWidth, mHeight);
//触发回掉
mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
//绘制
performDraw();
}
//2. post
View.java
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
//attachInfo 在ViewRootImpl.performTraversals()里面 dispatchAttachedToWindow的时候设置
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
mAttachInfo = info;
// Transfer all pending runnables.
if (mRunQueue != null) {
//加入到ViewRootImpl的handler
//final ViewRootHandler mHandler = new ViewRootHandler();
//正常这个handle是主线程的handler,所以在执行performTraversals之后将会执行这个,不如第一种方式的时机更快
mRunQueue.executeActions(info.mHandler);
mRunQueue = null;
}
}