Android的启动到View的绘制

2018-05-01  本文已影响0人  OkCoco

初始化WindowManagerService

获取WindowManagerService。

获取窗口并初始化

    public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
                                 boolean hardwareAccelerated) {
        ......
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }

    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
         return new WindowManagerImpl(mContext, parentWindow);
    }

    public WindowManager getWindowManager() {
        return mWindowManager;
    }

可以看出,mWindowManager其实是一个WindowManagerImpl实例。

给Window添加Activity布局

可以看出,当首次加载布局时,会走到:

    wm.addView(decor, l);

这里面,从上面可以知道,wm其实是一个WindowManagerImpl对象。看看源码:

@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    applyDefaultToken(params);
    mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}   

mGlobal是一个WindowManagerGlobal对象。

从这两段代码可以看出:

子线程不能更新UI

每一次导致布局刷新的操作都会操作到方法requestLayout(),这里开始了线程的检查;具体看源码:

    void checkThread() {
        if (mThread != Thread.currentThread()) {
            throw new CalledFromWrongThreadException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }

可以看出,当前操作UI的线程不是mThread的话,就会报子线程不能更新UI的操作。mThread是在ViewRootImpl的构造方法调用,该方法的调用链是:

ActivityThread[handleResumeActivity()]-->WindowManagerImpl[addView()]
-->WindowManagerGlobal[addView()]-->ViewRootImpl[构造方法]

即,mThread就是主线程(UI线程)。

View的绘制流程真正开始的地方

    void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            if (!mUnbufferedInputDispatch) {
                scheduleConsumeBatchedInput();
            }
            notifyRendererOfFramePending();
            pokeDrawLockIfNeeded();
        }
    }

final TraversalRunnable mTraversalRunnable = new TraversalRunnable();

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;
        }
    }
}

真正的View的绘制流程就从这里performTraversals开始了。

上一篇 下一篇

猜你喜欢

热点阅读