InputDispatcher这个类,它是Android事件输入系统的重要组成部分,整个Android事件输入系统可以分为几个部分。其首当其冲的是InputReader,其主要作用是将输入事件从硬件节点中读取后转化为一个Event事件,并将该事件分发给InputDispatcher,InputDispatcher的职责就是接收来自InputReader的Event事件,并像其名字所述的一样,将事件 发送给合适的窗口,并监控ANR的发生;然后则是创建InputReader和InputDispatcher的父类 (InputManager),由其创建两者并提供Policy对事件进行预处理;最后则是涉及系统Service以及面向用户的几个相关模块,如ActivityManager、WindowManager和View等。
在Android4.4中,事件输入的Service部分在/frameworks/base/services/input下,而在Android5.0中该部分实现至/frameworks/native/services/inputflinger/下,虽然我们将整个事件输入系统分为如上4个部分,但是,在android中负责管理事件输入是InputManagerService,其也是系统级的Service之一。
Android8.0中InputManagerServce在 base/services/core/java/com/android/server/input
public class InputManagerService extends IInputManager.Stub
implements Watchdog.Monitor {
... ...
}
public final class SystemServer {
... ...
}
/**
* Starts a miscellaneous grab bag of stuff that has yet to be refactored
* and organized.
*/
#SystemServer
private void startOtherServices() {
InputManagerService inputManager = null;
... ...
inputManager = new InputManagerService(context);
... ...
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore, new PhoneWindowManager());
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
... ...
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
... ...
}
从上述源码中可以看到,在SystemServer的startOtherServices方法中,不但构造并且启动了InputManagerService,而且在启动InputManagerService之前将它自身注入到WindowManagerService中进行关联。InputManagerService的构造函数主要是对native层初始化,但是它的实现逻辑非常复杂。
com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
return 0;
}
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
com_android_server_input_InputManagerService.cpp
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);
{
AutoMutex _l(mLock);
mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
mLocked.pointerSpeed = 0;
mLocked.pointerGesturesEnabled = true;
mLocked.showTouches = false;
mLocked.pointerCapture = false;
}
mInteractive = true;
sp<EventHub> eventHub = new EventHub();
mInputManager = new InputManager(eventHub, this, this);
}
//在NativeInputManager的逻辑中,首先会创建一个EventHub来监听所有事件的输入。
#InputManagerService
public class InputManagerService extends IInputManager.Stub
implements Watchdog.Monitor {
}
#InputManagerService
public InputManagerService(Context context) {
this.mContext = context;
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
mUseDevInputEventForAudioJack =
context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack="
+ mUseDevInputEventForAudioJack);
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
String doubleTouchGestureEnablePath = context.getResources().getString(
R.string.config_doubleTouchGestureEnableFile);
mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
new File(doubleTouchGestureEnablePath);
LocalServices.addService(InputManagerInternal.class, new LocalService());
}
#InputManagerService
private static native long nativeInit(InputManagerService service,
Context context, MessageQueue messageQueue);
这里主要是调用了nativeInit方法进行一些列的初始化操作,nativeInit 方法实现在native层,在其中构造了NativeInputManager对象。
之后就会相继初始化InputManager、InputDispatcher、InputReader、InputReaderThread和InputDispatcherThread。其中InputReaderThread 和
InputDispatcherThread是又InputManager管理的重要线程,其作用和具体的逻辑均与InputReader 和 InputDispatcher 相关。这一系列的初始化操作完毕后,InputManagerService就会在SystemServer里调用其start方法开始运作,其中最为主要的是,使上面提到的两个线程InputReaderThread 和 InputDispatcherThread 运作。InputReaderThread 启动后会进入死循环,每次循环都会调用loopOnce函数,第一次循环时会扫描/dev/input/设备节点目录,并通过ioctl函数获取设备信息以及判断其类型,当设备发生改变后则会通NativeInputManager 的回调函数通知处于java层的InputManagerService做出相应的处理。如上所述,InputReaderThread只负责从设备端读取事件信息,每一个事件信息在InputReaderThread里最终都会被封装为一个NotifyArgs对象,通过NotifyArgs中的Notify方法调用到InputDispatcher相应的Notify接口,并由InputDispatcher来完成事件的分派。
参考《Android源码设计模式》