Android(安卓)Input(一)-相关模块初始化
原创内容,转载请注明出处,多谢配合。
一、Android输入系统介绍
牵涉到的模块:
- InputReader: 负责从硬件获取输入,转换成事件(Event), 并传给Input Dispatcher.
- InputDispatcher: 将InputReader传送过来的Events分发给合适的窗口,并监控ANR。
- InputManagerService: 负责InputReader 和 InputDispatcher的创建,并提供Policy 用于Events的预处理。
- WindowManagerService:管理InputManager 与 View(Window) 以及 ActivityManager 之间的通信。
- View and Activity:接收按键并处理。
- ActivityManagerService:ANR 处理。
牵涉到的进程:
system_server 与 应用进程。
进程对应的主要工作线程:
其中system_server中包含InputReaderThread和InputDispatcherThread。
应用进程相关的主要是 UIThread。
二、初始化
在SystemServer的初始化过程中,IMS和WMS 被创建出来,并将WMS中的monitor传给了IMS,作为回调。
frameworks/base/services/java/com/android/server/SystemServer.javaprivate void startOtherServices() { WindowManagerService wm = null; 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(); ...}
IMS的构造方法中执行了nativeInit,这是个native方法,属于jni调用,该方法中创建了一个NativeInputManager实例,并且和java层使用的是同一个looper。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.javapublic InputManagerService(Context context) { this.mContext = context; this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper()); ... mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); ...}frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cppstatic jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { sp 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(im);}
在NativeInputManager的初始化中创建了一个Eventhub,同时将这个Eventhub传给新建的Inputmanager,Eventhub就是将数据从硬件驱动上读出来然后传递上来的通道。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cppNativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp& looper) : mLooper(looper), mInteractive(true) { ... sp eventHub = new EventHub(); mInputManager = new InputManager(eventHub, this, this);}
InputManager初始化时创建了两个重要操作类:InputReader
和InputDispatcher
。
frameworks/native/services/inputflinger/InputManager.cppInputManager::InputManager( const sp& eventHub, const sp& readerPolicy, const sp& dispatcherPolicy) { mDispatcher = new InputDispatcher(dispatcherPolicy); mReader = new InputReader(eventHub, readerPolicy, mDispatcher); initialize();}
initialize方法初始化对应的两个线程:InputReaderThread
和InputDispatcherThread
。
void InputManager::initialize() { mReaderThread = new InputReaderThread(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher);}
InputManager的start方法,让两个线程run起来。
frameworks/native/services/inputflinger/InputManager.cppstatus_t InputManager::start() { status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY); if (result) { ALOGE("Could not start InputDispatcher thread due to error %d.", result); return result; } result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); if (result) { ALOGE("Could not start InputReader thread due to error %d.", result); mDispatcherThread->requestExit(); return result; } return OK;}
那么这个InputManager的start方法在哪调的呢?回看IMS的start方法
frameworks/base/services/core/java/com/android/server/input/InputManagerService.javapublic void start() { Slog.i(TAG, "Starting input manager"); nativeStart(mPtr); ...}
这里又是调的native方法: nativeStart(mPtr)
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cppstatic void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) { NativeInputManager* im = reinterpret_cast(ptr); status_t result = im->getInputManager()->start(); if (result) { jniThrowRuntimeException(env, "Input manager could not be started."); }}
这里获取InputManager并调用它的start方法。
所以根据以上的初始化过程总结整个层次关系:
从这个初始化过程来看:IMS的逻辑基本上都是通过jni实现在native层。
下一篇文章:
Android Input(二)-输入子系统
更多相关文章
- Android性能优化一些方法
- android — JNI注册方法说明
- Android绘制圆形图片的3个方法
- Android(安卓)初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
- 深入理解SharedPrefences实现原理
- Android文件操作说明
- Android之提示错误Can not perform this action after onSaveIns
- Android中多USB摄像头解决方案——UVCCamera
- 【学习笔记】Android中Service通信