原創(chuàng)內(nèi)容,轉(zhuǎn)載請(qǐng)注明出處,多謝配合。
一、Android輸入系統(tǒng)介紹
牽涉到的模塊:
- InputReader: 負(fù)責(zé)從硬件獲取輸入,轉(zhuǎn)換成事件(Event), 并傳給Input Dispatcher.
- InputDispatcher: 將InputReader傳送過(guò)來(lái)的Events分發(fā)給合適的窗口,并監(jiān)控ANR。
- InputManagerService: 負(fù)責(zé)InputReader 和 InputDispatcher的創(chuàng)建,并提供Policy 用于Events的預(yù)處理。
- WindowManagerService:管理InputManager 與 View(Window) 以及 ActivityManager 之間的通信。
- View and Activity:接收按鍵并處理。
- ActivityManagerService:ANR 處理。
牽涉到的進(jìn)程:
system_server 與 應(yīng)用進(jìn)程。
進(jìn)程對(duì)應(yīng)的主要工作線程:
其中system_server中包含InputReaderThread和InputDispatcherThread。
應(yīng)用進(jìn)程相關(guān)的主要是 UIThread。
二、初始化
在SystemServer的初始化過(guò)程中,IMS和WMS 被創(chuàng)建出來(lái),并將WMS中的monitor傳給了IMS,作為回調(diào)。
frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {
WindowManagerService wm = null;
InputManagerService inputManager = null;
…
inputManager = new InputManagerService(context);
...
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
…
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
...
}
IMS的構(gòu)造方法中執(zhí)行了nativeInit,這是個(gè)native方法,屬于jni調(diào)用,該方法中創(chuàng)建了一個(gè)NativeInputManager實(shí)例,并且和java層使用的是同一個(gè)looper。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
...
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
...
}
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
在NativeInputManager的初始化中創(chuàng)建了一個(gè)Eventhub,同時(shí)將這個(gè)Eventhub傳給新建的Inputmanager,Eventhub就是將數(shù)據(jù)從硬件驅(qū)動(dòng)上讀出來(lái)然后傳遞上來(lái)的通道。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
NativeInputManager::NativeInputManager(jobject contextObj,
jobject serviceObj, const sp<Looper>& looper) :
mLooper(looper), mInteractive(true) {
...
sp<EventHub> eventHub = new EventHub();
mInputManager = new InputManager(eventHub, this, this);
}
InputManager初始化時(shí)創(chuàng)建了兩個(gè)重要操作類:InputReader
和InputDispatcher
。
frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
initialize();
}
initialize方法初始化對(duì)應(yīng)的兩個(gè)線程:InputReaderThread
和InputDispatcherThread
。
void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
InputManager的start方法,讓兩個(gè)線程run起來(lái)。
frameworks/native/services/inputflinger/InputManager.cpp
status_t InputManager::start() {
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputDispatcher thread due to error %d.", result);
return result;
}
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
if (result) {
ALOGE("Could not start InputReader thread due to error %d.", result);
mDispatcherThread->requestExit();
return result;
}
return OK;
}
那么這個(gè)InputManager的start方法在哪調(diào)的呢?回看IMS的start方法
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
...
}
這里又是調(diào)的native方法: nativeStart(mPtr)
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();
if (result) {
jniThrowRuntimeException(env, "Input manager could not be started.");
}
}
這里獲取InputManager并調(diào)用它的start方法。
所以根據(jù)以上的初始化過(guò)程總結(jié)整個(gè)層次關(guān)系:
從這個(gè)初始化過(guò)程來(lái)看:IMS的邏輯基本上都是通過(guò)jni實(shí)現(xiàn)在native層。
下一篇文章:
Android Input(二)-輸入子系統(tǒng)