Android

Android输入管理_InputManager服务启动

2017-09-06  本文已影响82人  gczxbb

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启动,目的是让底层两个线程运行起来,两线程均是无限循环线程,不停的获取事件消息进行分发。


任重而道远

上一篇下一篇

猜你喜欢

热点阅读