美文网首页
Android系统输入事件启动

Android系统输入事件启动

作者: 我叫王菜鸟 | 来源:发表于2017-12-15 19:53 被阅读0次

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

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

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

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

    • InputDispatcher.cpp
    • InputReader.cpp
    • InputManager.cpp
    • EventHub.cpp
    • InputListener.cpp

    对于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;
    }
    

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

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

    • 在native中创建了NativeInputManager对象,并且将NativeInputManager对象的指针交到java层的mPtr中保存起来,mPtr存在与IMS中
    • 在这个过程中创建了几个核心的类:
      • NativeInputManager :native层的管理
      • EventHub:将多种格式的消息统一成一种格式给framework使用
      • InputManager:用于创建对应的InputReader与InputDispatcher核心的类
      • InputReaderThread:对应读取事件的线程
      • InputDispatcherThread:对应分发事件的线程
    • 在这里面包含了3个线程
      • 一开始在framework的DisplayThread:有自己的Looper
      • InputReaderThread
      • InputDispatcherThread:有自己的Looper

    相关文章

      网友评论

          本文标题:Android系统输入事件启动

          本文链接:https://www.haomeiwen.com/subject/otndwxtx.html