Android系统输入事件启动

2017-12-15  本文已影响0人  我叫王菜鸟

以后我打算换一种写法,前面的文章很多都是大段大段代码往上扔,别说大家了,我想回过头来看的时候都觉得恶心,所以我以后叙述多一些,多说一些原理性的东西,这样让人一看就知道怎么回事。

简介
输入事件是目前我发现第2个使用到socket传输的机制,这部分内容启动过程比较简单,读取过程也比较简单,但是分发机制就比较复杂,因为牵扯到WMS对应的内容,负责要将事件分发到那个窗口,所以我们就由简单到深入了解一下Android中输入事件机制。

首先我们从InputManagerService开始,InputManagerService是输入事件的管理者,就和我们的WMS,ANS,PMS一样起着管理作用。那我们就按照惯例从构造看。

InputManagerService在构造的时候期初创建了几个核心的类:

对于InputDispatcher与InputReader来说一个是用于分发事件一个是用来获取事件。所以如果我们需要设计,肯定是两个线程,两个死循环,一个不断读取,一个不断分发。那么Android系统里面是如何做的呢?

系统中用InputManager来管理InputDispatcher与InputReader对应的线程

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有自己的Looper对象。那InputDispatcher与InputReader是通过什么链接起来的呢?

在InputReader中

InputReader::InputReader(const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& policy,
        const sp<InputListenerInterface>& listener) :
        mContext(this), mEventHub(eventHub), mPolicy(policy),
        mGlobalMetaState(0), mGeneration(1),
        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    // 创建输入监听对象
    mQueuedListener = new QueuedInputListener(listener);
    {
        AutoMutex _l(mLock);
        refreshConfigurationLocked(0);
        updateGlobalMetaStateLocked();
    }
}

其中const sp<InputListenerInterface>& listener就是将InputDispatcher对象传递到InputReader中然后传到QueuedInputListener里面。

这样就理清楚了,InputManager创建了InputReader,InputDispatcher并且InputReader持有InputDispatcher的引用。

对应工作线程

void InputManager::initialize() {
    //创建线程“InputReader”
    mReaderThread = new InputReaderThread(mReader);
    //创建线程”InputDispatcher“
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
}

InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
        Thread(/*canCallJava*/ true), mReader(reader) {
}

InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
}

这两个国宝级别的线程在InputManagerService.start的时候开始工作

public void start() {
    nativeStart(mPtr);
}

在native里面使用的NativeInputManager其中的InputManager进行start

status_t InputManager::start() {
    result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    ...
    return OK;
}

最后终于启动了两个国宝线程

小结启动过程中的相关事情

上一篇下一篇

猜你喜欢

热点阅读