…
…
ViewRootImpl root;
View panelParentView = null;
…
…
1.创建ViewRootImpl对象
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
// do this last because it fires off messages to start doing things
try {
2.调用ViewRootImpl的setView方法
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}
注释1是个很重要的点,这里创建了一个ViewRootImpl对象。
我们来解析一下这个ViewRootImpl里面需要关注的几个点。
我们先看看ViewRootImpl的构方法:
public ViewRootImpl(Context context, Display display) {
//获取Session对象
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplay = display;
mBasePackageName = context.getBasePackageName();
//主线程
mThread = Thread.currentThread();
//创建Choreographer对象,这个对象很重要,可以把它理解为一个Handler
//Android 16.6ms刷新一次页面它启到了主要作用
//我们马上看看这个Choreographer是个什么
mChoreographer = Choreographer.getInstance();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
}
ViewRootImpl的构造方法里面我们暂时值关注两件事
1.获取了Session对象这个对象是我们与WindowManagerService交互的桥梁。
2.创建了Choreographer对象。
我们现来看看这个Choreographer对象到底是什么,为什么它那么重要呢?
public static Choreographer getInstance() {
return sThreadInstance.get();
}
// Thread local storage for the choreographer.
private static final ThreadLocal sThreadInstance =
new ThreadLocal() {
@Override
protected Choreographer initialValue() {
//注意了这里其实就是主线程的Looper
//ViewRootImpl对象就是在主线程创建的
Looper looper = Looper.myLooper();
if (looper == null) {
throw new IllegalStateException(“The current thread must have a looper!”);
}
//创建Choreographer对象
Choreographer choreographer = new Choreographer(looper, VSYNC_SOURCE_APP);
if (looper == Looper.getMainLooper()) {
mMainInstance = choreographer;
}
return choreographer;
}
};
private Choreographer(Looper looper, int vsyncSource) {
mLooper = looper;
//前面我们说了正常情况瞎这个looper对象就是主线程的looper对象
//所以通过这个Handler发送的消息都是在主线程处理的
mHandl