Android 滑動衝突處理及事件分發機制

滑動衝突

顧名思義,即爲子佈局與父佈局同時可滑動時可能造成的一種衝突情況,一般主要分爲一下兩種類型

  • 外部佈局與內部佈局滑動方向不一致,例如ScrollView嵌套ViewPager
  • 外部佈局與內部佈局滑動方向一致,例如ScrollView嵌套ListView,ViewPager嵌套ViewPager

 要想了解滑動衝突的根本原因和解決辦法,我們先了解一下Android的事件分發機制

觸摸事件產生

Android整個觸摸事件產生過程可以分爲 linux層  ==>  native層 ==> java層 

linux層:

由於Android底層是linux,所以Android也是採取跟linux相同的方式處理用戶輸入事件,那就是中斷的方式。當用戶觸摸到屏幕是,觸摸屏會產生相應的中斷,並由其驅動程序處理該中斷,最終將採集到的數據處理之後存放進了對應的/dev/input/eventX文件中

native層:

native層對於觸摸事件主要靠三個組件,分別是EventHub,InputReader,InputDispatcher。

EventHub主要負責監聽讀取/dev/input目錄下產生的事件,並封裝成RawEvent結構給InputReader

InputReader從EventHub那獲取事件信息後轉化成EventEntry事件加入到InputDispatcher的mInboundQueue隊列中

InputDispatcher最終從mInboundQueue隊列取出事件,轉化爲DispatchEntry事件加入到Connection的outboundQueue隊列,然後使用InputChannel利用socket跨進程通信的原理分發事件到java層,這個暫先不討論。

Android本身主線程是默認開啓Looper不斷從MessageQueue隊列中獲取消息,但是MessageQueue創建時同樣創建了一個NativeMessageQueue隊列,用於接收native層的消息

  1. loop每次循環時便通過nativePollOnce方法讀取該隊列,並調用Looper.pollInner方法
  2. 這個方法最終又會回調NativeInputEventReceiver.handleEvent方法。
  3. 而在這個方法中主要又是通過調用consumeEvents方法進行事件處理。
  4. consumeEvents方法會產生MotionEvent對象,並通過jni的gInputEventReceiverClassInfo.dispatchInputEvent方法
  5. 而jni的這個方法最終就調用了java層的InputEventReceiver.dispatchInputEvent方法正式進入到java層事件分發

java層

java層通過inputEventReceiver.dispatchInputEvent方法最終調用Activity.dispatchTouchEvent進入到Android事件分發機制之中

事件分發

Mark一下 Android事件分發機制詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章