天天看點

Touch事件的産生及傳遞到DecorView的路線Touch事件的産生

Touch事件的産生

之前寫了一篇touchEvent分發的,講了事件在ViewGruop中的傳遞。

這篇記錄下學習的事件生成的大緻過程。

首先是事件服務的初始化部分。

這部分的核心是native部分的架構。有很多C++的代碼,我基本選擇略過。

服務的啟動涉及到 WindowManagerService -> InputManagerService .

然後是native層的 NativeInputManager -> InputManager .

InputManager包含 InputDispatcher 和 InputReader .

這兩個會被封裝成兩個線程 InputReaderThread 和 InputDispatcherThread ,分别負責讀和分發。

跳過一大段, 到 InputChannel 和 NativeInputEventReceiver.cpp 再調用到 InputEventReceiver.java 的 dispatchInputEvent。

子類 WindowInputEventReceiver 中開始方法跳轉 onInputEvent -> enqueueInputEvent

-> doProcessInputEvents -> deliverInputEvent -> stage.deliver(q) .

stage是個InputStage對象. 在這個對象的 processPointerEvent 方法中,調用的view的dispatchPointerEvent方法。

這時候對象就來到了 DecorView ,即Window 的最底層View. 也是PhoneWindow 的 内部類。

從DecorView開始又要繞繞圈了。

DecorView 的 dispatchTouchEvent 裡有句 cb.dispatchTouchEvent(ev) 。cd是個 Window.Callback 對象。Activity實作了這個接口 。cb實際就是Activity,那麼就會調用Activity的 dispatchTouchEvent 方法。

public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }
           

可以看到,調用了 getWindow().superDispatchTouchEvent(ev) 。并且同View的傳遞機制一樣,如果 getWindow().superDispatchTouchEvent(ev) 不消費該事件,才會 調用Activity自己的onTouchEvent 。

這句getWindow().superDispatchTouchEvent(ev) 會調用到PhoneWindow的superDispatchTouchEvent。 然後調用到DecorView 的 superDispatchTouchEvent。

最終調用super.dispatchTouchEvent 。DecorView繼承自 FrameLayout ,是以,實際調用ViewGroup的 dispatchTouchEvent。自此成功傳遞到了View的視圖層級中,可以開始層級中的分發了。

以下是一個比較細的底層代碼分析。

http://www.cnblogs.com/haiming/p/3318614.html