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