Android 淺析 消息事件分發(fā)機制

事件系統(tǒng)

事件系統(tǒng)分為四部分:采集信息、前期處理、WMS分配、應用程序處理。

  • 采集信息:就是硬件部分收集點擊的事件。
  • 前期處理:對剛收集的事件進行格式處理。
  • WMS 分配:WMS 記錄了當前系統(tǒng)所有窗口完整狀態(tài)信息,所以可以判斷事件投遞的具體進程。
  • 應用程序處理:最后派發(fā)給應用程序讓我們自己來處理。

1. 采集信息

采集信息基本都是硬件部分的事,無論對屏幕的觸碰事件還是鍵盤的點擊事件都是由手機硬件采集,然后保存在本地的一個事件文件里面。

2. 前期處理

在采集完信息后要做最初的事件處理,例如分類:Home、Back、Menu等。事件類型:拖動、點擊、其它等。

3. WMS 分配事件

Android系統(tǒng)中負責管理輸入事件的主要是InputManagerService(IMS)。它主要的任務就是從設備中讀事件數(shù)據(jù),然后將輸入事件發(fā)送到焦點窗口中去,另外還需要讓系統(tǒng)有機會來處理一些系統(tǒng)按鍵。

InputManagerService里包含了兩個非常重要的工作線程。

3.1 InputReaderThread

一個獨立的循環(huán)線程,主要任務就是不斷地輪詢相關設備節(jié)點查看是否有新的事件發(fā)生。并將事件告知派發(fā)系統(tǒng)。

3.2 InputDispatcherThread

一個獨立的線程,用以處理從事件輪詢系統(tǒng)告知過來的事件,保證事件的正確派發(fā)和處理。

在初始化的最初會以參數(shù)的形式將InputDispatcherThread的對象封裝進InputReaderThread里,在InputReader的loopOnce循環(huán)里會不斷通過Dispatcher將事件發(fā)送給Listener。

InputDispatcherThread 的一個核心工作就是確定事件的接收對象。

在WMS 和 InputDispatcher 的中間存在著一個InputMonitor對象,這個對象作為中介,工作主要分為兩部分,第一:實現(xiàn)WindowManagerCallbacks接口,WindowManagerCallbacks包含了一些例如輸入設備的配置變更,連接InputDispatcher與應用程序Socket通道,等等的接口。第二:為WMS 訪問InputDispatcher提供函數(shù)實現(xiàn)。比如InputDispatcher中當前焦點窗口,就是WMS 通過InputMonitor來獲取的。

3.2.1 通知應用程序窗口

InputDispatcher與應用程序的通信不是通過Binder來實現(xiàn),而是通過管道channel來實現(xiàn),就是Unix Domain Socket 實現(xiàn),并且是一個雙向的通道。因為重點是所有的應用程序都會在WMS里有注冊,所以也只有WMS 能正確派發(fā)事件。

4. 應用程序處理

在經(jīng)過InputDispatcher傳入事件后,就由用戶的應用程序來處理最后的事件了。

首先,我們來看下事件的分發(fā)流程。

4.1 事件分發(fā)但一直沒處理

分發(fā)流程
分發(fā)流程

4.2 事件分發(fā)并且處理了

分發(fā)流程1
分發(fā)流程1

4.3 事件分發(fā)并且被layout消費

分發(fā)流程2
分發(fā)流程2

通過這三個圖我們就可以很清楚的看到事件的分發(fā)流程順序,并且在處理與不處理的反饋上清晰明了。

重點說下,在事件被分發(fā)到View層的時候如果同時監(jiān)聽了OnTouchListener、OnClickListener,那么很遺憾,如果在OnTouchListener消費了這個事件,那么clicklistener是無法接收這個事件的,原因就是因為在View派發(fā)消息時:

public boolean dispatchTouchEvent(MotionEvent event) {  
    if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&  
            mOnTouchListener.onTouch(this, event)) {  
        return true;  
    }  
    return onTouchEvent(event);  
}

mOnTouchListener.onTouch(this, event)這個函數(shù)優(yōu)于onTouchEvent(event)前處理。如果想OnClickListener也可以處理也很簡單,onTouch(...)返回false就行了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,008評論 25 709
  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,378評論 6 13
  • 3.3 Android窗口 3.3.1 概述 Android系統(tǒng)中,窗口管理系統(tǒng)是基于C/S模式的,客戶端(App...
    jianhuih閱讀 2,216評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,551評論 19 139
  • 秋雨連綿的盡頭 終于看到了久違的太陽 它在霧靄里悄悄張望 那是幸福的感覺 十月末的太陽 我要和你做永久的情人 再不...
    Harvest收獲閱讀 1,031評論 68 111

友情鏈接更多精彩內(nèi)容