美文网首页Android
Android输入管理_InputManager服务启动

Android输入管理_InputManager服务启动

作者: gczxbb | 来源:发表于2017-09-06 17:35 被阅读82次

    Android输入系统采用生产者_消费者模型,生产者(触屏)负责制造事件,消费者(视图)负责事件派发。

    InputManagerService服务

    Android系统服务运行于system_server进程,核心服务如Ams、Wms,Pms等,其中包括Ims,SystemServer负责启动系统服务。
    SystemServer#startOtherServices方法。

    private void startOtherServices() {
        ...
        //创建Ims对象
        InputManagerService inputManager = null;
        inputManager = new InputManagerService(context);
        //启动
        inputManager.start();
        final InputManagerService inputManagerF = inputManager;
        if (inputManagerF != null) inputManagerF.systemRunning();
        ...
    }
    
    输入管理服务架构如下图所示。 输入管理服务架构图.jpg

    创建与初始化

    由服务架构图可知,Java层有一个InputManagerService对象,在构造方法中,创建底层NativeInputManager对象。
    InputManagerService#构造方法。

    public InputManagerService(Context context) {
        this.mContext = context;
        this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
        //DisplayThread线程消息队列
        mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
        ....
    }
    

    JNI#nativeInit方法。

    static jlong nativeInit(JNIEnv* env, jclass /* clazz */,jobject serviceObj, 
                    jobject contextObj, jobject messageQueueObj) {
        sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, 
                        messageQueueObj);
        //消息队列为空异常返回0
        ...
        NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
                messageQueue->getLooper());
        im->incStrong(0);
        return reinterpret_cast<jlong>(im);
    }
    

    创建底层NativeInputManager,封装真正服务InputManager,返回mPtr指针。MessageQueue是DisplayThread线程消息队列。
    NativeInputManager#构造方法。

    NativeInputManager::NativeInputManager(jobject contextObj,
            jobject serviceObj, const sp<Looper>& looper) :
            mLooper(looper), mInteractive(true) {
        JNIEnv* env = jniEnv();
        mContextObj = env->NewGlobalRef(contextObj);
        mServiceObj = env->NewGlobalRef(serviceObj);
        ...
        mInteractive = true;
        sp<EventHub> eventHub = new EventHub();
        mInputManager = new InputManager(eventHub, this, this);
    }
    

    创建EventHub与InputManager,mContextObj与mServiceObj分别是上层Context与Ims对象。

    EventHub:通过Linux系统调用获取底层设备事件,向InputReader传递。
    InputManager:启动事件读取/分发线程,管理读取/分发类。

    InputManager#构造方法。

    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继承QueuedInputListener,在InputReader内部,QueuedInputListener作为事件监听。
    InputManager#initialize方法。

    void InputManager::initialize() {
        mReaderThread = new InputReaderThread(mReader);
        mDispatcherThread = new InputDispatcherThread(mDispatcher);
    }
    

    初始化读取/分发线程,封装读取分发类。InputReaderThread是事件读取线程,该线程利用threadLoop实现无限循环,利用InputReader不断获取事件消息,从InputManager的构造方法可知,InputReader创建时封装了EventHub与InputDispatcher
    因此,在InputReader中,EventHub将读取到的事件消息交给InputDispatcher。

    Ims服务启动

    InputManagerService#start方法。

    public void start() {
        //native层启动方法,调用native层InputManager的start方法
        nativeStart(mPtr);
        ...
    }
    

    JNI#nativeStart方法。

    static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
        NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);    
        status_t result = im->getInputManager()->start();
    }
    

    底层InputManager#start方法。

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

    启动读取/分发线程,threadLoop循环。
    读取线程

    bool InputReaderThread::threadLoop() {
        mReader->loopOnce();
        return true;
    }
    

    利用InputReader#loopOnce获取事件。
    分发线程

    bool InputDispatcherThread::threadLoop() {
        mDispatcher->dispatchOnce();
        return true;
    }
    

    利用InputDispatcher#dispatchOnce实现一次分发。
    InputManager服务启动成功。

    总结:输入管理架构主要包括上层InputManagerService服务,底层管理者NativeInputManager与InputManager,其中NativeInputManager与上层指针联系,InputManager负责真正的底层管理,事件获取者EventHub,读取分发InputReader与InputDispatcher。
    以上架构建立后,从上层Ims调用start启动,目的是让底层两个线程运行起来,两线程均是无限循环线程,不停的获取事件消息进行分发。


    任重而道远

    相关文章

      网友评论

        本文标题:Android输入管理_InputManager服务启动

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