原創(chuàng)內容呛每,轉載請注明出處揍愁,多謝配合。
一纸厉、Android輸入系統(tǒng)介紹
牽涉到的模塊:
- InputReader: 負責從硬件獲取輸入,轉換成事件(Event), 并傳給Input Dispatcher.
- InputDispatcher: 將InputReader傳送過來的Events分發(fā)給合適的窗口五嫂,并監(jiān)控ANR颗品。
- InputManagerService: 負責InputReader 和 InputDispatcher的創(chuàng)建,并提供Policy 用于Events的預處理。
- WindowManagerService:管理InputManager 與 View(Window) 以及 ActivityManager 之間的通信抛猫。
- View and Activity:接收按鍵并處理蟆盹。
- ActivityManagerService:ANR 處理。
牽涉到的進程:
system_server 與 應用進程闺金。
進程對應的主要工作線程:
其中system_server中包含InputReaderThread和InputDispatcherThread逾滥。
應用進程相關的主要是 UIThread。
二败匹、初始化
在SystemServer的初始化過程中寨昙,IMS和WMS 被創(chuàng)建出來,并將WMS中的monitor傳給了IMS掀亩,作為回調舔哪。
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的構造方法中執(zhí)行了nativeInit,這是個native方法槽棍,屬于jni調用捉蚤,該方法中創(chuàng)建了一個NativeInputManager實例,并且和java層使用的是同一個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)建了一個Eventhub缆巧,同時將這個Eventhub傳給新建的Inputmanager,Eventhub就是將數(shù)據(jù)從硬件驅動上讀出來然后傳遞上來的通道豌拙。
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初始化時創(chuàng)建了兩個重要操作類: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方法初始化對應的兩個線程:InputReaderThread
和InputDispatcherThread
。
void InputManager::initialize() {
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
}
InputManager的start方法按傅,讓兩個線程run起來捉超。
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;
}
那么這個InputManager的start方法在哪調的呢?回看IMS的start方法
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
public void start() {
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
...
}
這里又是調的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并調用它的start方法唯绍。
所以根據(jù)以上的初始化過程總結整個層次關系:
從這個初始化過程來看:IMS的邏輯基本上都是通過jni實現(xiàn)在native層拼岳。
下一篇文章:
Android Input(二)-輸入子系統(tǒng)