专栏名称: 刘望舒
腾讯云最具价值专家
目录
相关文章推荐
复利大王  ·  某航离谱瓜! ·  14 小时前  
复利大王  ·  好牛的幼儿园 ·  昨天  
复利大王  ·  湘ya一骨科的瓜? ·  昨天  
复利大王  ·  不讲武德!中x银行? ·  昨天  
鸿洋  ·  务必立即拿下软考证(政策红利) ·  2 天前  
51好读  ›  专栏  ›  刘望舒

Android输入系统(二)IMS的启动过程和输入事件的处理

刘望舒  · 掘金  · android  · 2018-11-20 14:56

正文

请到「今天看啥」查看全文


 private void startOtherServices() {
 ...
         traceBeginAndSlog("StartInputManagerService");
         inputManager = new InputManagerService(context);
         traceEnd();
 ...
         traceBeginAndSlog("StartInputManager");
         inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
         inputManager.start();
         traceEnd();

}
复制代码

创建IMS后就会紧接着执行IMS的启动。IMS的start方法如下所示。 frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

 public void start() {
        Slog.i(TAG, "Starting input manager");
        nativeStart(mPtr);
        // Add ourself to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this);
      ...
    }
复制代码

IMS的start方法中,会将自身添加到Watchdog中进行监控,用于定时检测系统关键服务(AMS和WMS等)是否可能发生死锁。 nativeStart方法对应的JNI层的函数是什么呢?查看com_android_server_input_InputManagerService的gInputManagerMethods数组,不理解JNI的可以查看 深入理解JNI 系列文章。 frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

static const JNINativeMethod gInputManagerMethods[] = {
...
   { "nativeStart", "(J)V",
            (void*) nativeStart },
...
}
复制代码

nativeStart方法对应的JNI函数为nativeStart: 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();//1
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}
复制代码

用reinterpret_cast操作符将jlong类型的ptr强制转换为原类型(NativeInputManager指针类型)。注释1处会调用InputManager的start函数。 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函数运行了InputReaderThread和InputDispatcherThread,这两个线程在 Android输入系统(一)输入事件传递流程和InputManagerService的诞生 提到过,它们在InputManager的构造函数中被创建,其中InputReaderThread中运行了InputReader, InputDispatcherThread中运行了InputDispatcher。

2.InputDispatcher的启动过程

先来回顾下InputDispatcher和InputReader是在哪创建的,InputManager的构造函数如下所示。 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();
}
复制代码

可以看到InputDispatcher和InputReader是有关联的,InputDispatcher会作为一个参数传入到InputReader中。 InputDispatcher是在InputReader之前创建的,这个顺序不能改变,因为要确保InputReader将加工后的输入事件交给InputDispatcher时,InputDispatcher已经被创建。 InputDispatcher的定义如下所示。 frameworks/native/services/inputflinger/InputDispatcher.h







请到「今天看啥」查看全文


推荐文章
复利大王  ·  某航离谱瓜!
14 小时前
复利大王  ·  好牛的幼儿园
昨天
复利大王  ·  湘ya一骨科的瓜?
昨天
复利大王  ·  不讲武德!中x银行?
昨天
网易蜗牛读书  ·  李银河:我得到了一张特殊的入场券
7 年前