歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android 2.3 input輸入事件處理

Linux內核提供了一個Input子系統來實現的,Input子系統會在/dev/input/路徑下創建我們硬件輸入設備的節點,一般情況下在我們的手機中這些節點是以eventXX來命名的,如event0,event1等等,可以利用EVIOCGNAME獲取此事件結點名稱。這就是Android中對於input事件處理數據的來源點,至於驅動寫入數據這塊就不說了。

首先,簡而言之的介紹一下android事件傳遞的流程,按鍵,觸屏等事件是經由WindowManagerService獲取,並通過共享內存和管道的方式傳遞給ViewRoot,ViewRoot再dispatch給Application的View。當有事件從硬件設備輸入時,system_server端在檢測到事件發生時,通過管道(pipe)通知ViewRoot事件發生,此時ViewRoot再去的內存中讀取這個事件信息。下面以一個模塊劃分圖了解一下整個過程:

下面詳細介紹一個各個模塊主要處理流程:

1、建立通讀通道初始化:

A、WindowManagerService與ViewRoot建立管道初始化

WindowManagerService : 主要負責事件傳遞,運行於system_server中,主要利用inputmanager啟動input事件啟動線程

讀取event數據

WindowManagerService--->ViewRoot方向的管道通信,表示WMS通知ViewRoot有新事件被寫入到共享內存;


     ViewRoot-->WindowManagerService方向的管道通信,表示ViewRoot已經消化完共享內存中的新事件,特此通知WMS。

     ViewRoot和WindowManagerService的管道的文件描述符都是被存儲在一個名為InputChannel的類中,這個InputChannel類是

管道通信的載體。而這兩者間通過ashmem_create_region創建匿名內存進行數據的傳遞 。

ViewRoot.java 端建立管道:

mInputChannel = new InputChannel();
                try {
                    res = sWindowSession.add(mWindow, mWindowAttributes,
                            getHostVisibility(), mAttachInfo.mContentInsets,
                            mInputChannel);
                } catch (RemoteException e)

WindowManagerService.java 建立管道:

if (outInputChannel != null) {
                String name = win.makeInputChannelName();
                InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
                win.mInputChannel = inputChannels[0];
                inputChannels[1].transferToBinderOutParameter(outInputChannel);
               
                mInputManager.registerInputChannel(win.mInputChannel);
            }

創建一對InputChannel,這一對InputChannel中實現了一組全雙工管道及申請共享內存,其中outInputChannel為ViewRoot傳遞來的

InputChannel對象,在addWindow中對其進行賦值。如此兩者利用pipe建立控制通道,利用共享內存建立數據通道。

這是涉及到的文件如下:

frameworks/base/service/java/com/android/server/WindowManagerService.java

frameworks/base/core/java/android/view/ViewRoot.java

--> jni android_view_InputChannel.cpp

--> InputTransport.cpp


B、InputChannel的注冊過程

一個管道通信只是對應一個Activity的事件處理,也就是當前系統中有多少個Activity就會有多少個全雙工管道,那麼系統需要一個管理者來管理以及調度每一個管道通信,因此我們在創建完InputChannel對象後,需要將其注冊到這個InputManager管理中。

采用Looper來輪詢是否有事件發生,InputManager啟動了2個進程來管理事件發生與傳遞,InputReaderThread和InputDispatcherThread,InputReaderThread進程負責輪詢事件發生; InputDispatcherThread負責dispatch事件。

Copyright © Linux教程網 All Rights Reserved