Android體系架構之事件分發機制探究

       事件分發是作爲一名Android開發者必須要掌握的東西,下面我們來一起探究下是如何進行事件分發的
首先我們要搞明白,什麼是事件分發?Android中的視圖是由一個個View嵌套構成的層級視圖,即一個View裏包含有子View,而這個子View裏面又可以再添加View。當用戶觸摸屏幕產生一系列事件時,事件會由高到低,由外向內依次傳遞,最終把事件交到一個具體的View手上處理,這個傳遞的過程就叫做事件分發。
事件分發的順序 Activity->ViewGroup->View
支持事件分發的方法dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent
下面我們先來探究下事件分發的順序
當手機屏幕發生了點擊事件時,首先調用的是Activity的dispatchTouchEvent方法,起主要代碼如下:
if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
return onTouchEvent(ev);
 
調用了getWindow().superDispatchTouchEvent(ev)方法,
public Window getWindow() {
return mWindow;
}
 
getWindow方法返回了一個Window對象,這個Window對象是一個抽象類,他的唯一實現是PhoneWindow,你說我是怎麼知道的?上註釋
 
好的我們在去PhoneWindow中看下superDispatchTouchEvent方法,源碼是在frameworks層。路徑
.frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
// This is the top-level view of the window, containing the window decor.
   private DecorView mDecor;
   public boolean superDispatchTouchEvent(MotionEvent event) {
        return mDecor.superDispatchTouchEvent(event);
    }    
到這裏發現了DecorView,幹啥的呢?註釋說明的很清楚,他是window的頂層視圖
我們在去DecorView中看下superDispatchTouchEvent方法
public boolean superDispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); }
調用了父類的dispatchTouchEvent, DecorView extends FrameLayout,有的人說我怎麼在FrameLayout中找不到這個方法呢,是的我也找不到爲啥呢?FrameLayout extends ViewGroup,明白了吧,我們直接去ViewGroup中看看有沒有
代碼太多就不放了,路徑在android.view下
在ViewGroup中的dispatchTouchEvent方法默認訪問了onInterceptTouchEvent
// Check for interception.
final boolean intercepted;
intercepted = onInterceptTouchEvent(ev);
然後調用了dispatchTransformedTouchEvent並傳遞了四個參數,注意第三個參數是null
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
 dispatchTransformedTouchEvent方法中,第三個參數是child,看看child==null時做了什麼操作
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits)
 
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
handled = child.dispatchTouchEvent(event);
}
child是null時,調用了父類的dispatchTouchEvent方法,我們在接着往下看ViewGroup extends View,
直接看View中的dispatchTouchEvent方法,在View中的dispatchTouchEvent方法中調用了自身的onTouchEvent方法,並默認返回一個false。
到這裏整個事件的分發順序我們是不是就清楚了,Activity->ViewGroup->View,老鐵們,很清楚有木有!有的同學要說了View默認返回false或者有返回true的情況在然後呢,下面這些就不一一分析了,一大段的代碼文字看着也煩,大家根據我這個思路自己過一遍framework源碼即可,下面在給大家整體上一張事件分發流程圖
 
 
簡單的總結下:
Activity收到觸屏分發事件後對自己的dispatchTouchEvent說,你給我把這個事件處理下,Activity的dispatchTouchEvent收到指令不想幹,他對他的小弟ViewGroup中的dispatchTouchEvent說你把這個事件處理下,ViewGroup中的dispatchTouchEvent也不想幹活啊,他對自己家的onInterceptTouchEvent說,這個事件交給你,趕緊處理下,onInterceptTouchEvent也是有脾氣的,你們都不幹讓我幹,我也不幹,他手下也有小弟,於是對他手下的小弟View中的dispatchTouchEvent說,這個問題你看看,是不是你們團隊的搞的bug,趕緊處理下,View團隊的dispatchTouchEvent於是將問題提交給了他們團隊專門處理問題的onTouchEvent,onTouchEvent經過三天三夜的苦戰研究發現解決不了,於是上報給了ViewGroup團隊的onTouchEvent,ViewGroup團隊的onTouchEvent接到小弟的上報問題後,發現自己也處理不了,於是又上報給了Activity團隊的onTouchEvent,Activity團隊的onTouchEvent接到小弟的上報問題後發現時間過去太久了,客戶都不用這個系統了,直接扔一邊去了愛咋地咋地吧。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章