Android Input输入子系统分析
2015-09-08 14:31
204 查看
最开始接触android系统便是touch驱动,属于典型的input输入子系统设备,但是从未认真总结过,蓦然回首,总结一下:
input输入子系统是对一些输入设备的总体规划,标准的接口,外设中诸如键盘,鼠标,触摸屏等都是典型的input设备,这些设备的事件处理都是走input输入子系统流程,而input系统在底层有相应的驱动,在上层有相应的守护server,首先看InputManagerService的启动:
首行便是初始化一个InputManagerService的实例,
nativeInit方法:
代码段如下:
初始化InputManager实例;
initialize()方法,初始化两个线程,InputReader和InputDispatcher等,
回到一开始的代码段的紫色行,代码调用了inputManager的start()方法:
红色标注的代码段是关键,
调用至InputManager的start()方法;
末段,开启了上边提到的两个关键线程,mDispatcherThread和mReaderThread,后面继续分析input子系统在上层的这两个关键线程:大体流程就是ReaderThread通过EventHub获取kernel上报的input事件,唤醒DispatherThread去处理相关input事件,Dispatcher根据事件的类型以及有效性做一个判断,从而决定事件发送不发送,发送给谁等。详细的方法调用流程,后面的文章会做分析。。。先告一段落!
input输入子系统是对一些输入设备的总体规划,标准的接口,外设中诸如键盘,鼠标,触摸屏等都是典型的input设备,这些设备的事件处理都是走input输入子系统流程,而input系统在底层有相应的驱动,在上层有相应的守护server,首先看InputManagerService的启动:
inputManager = new InputManagerService(context, wmHandler); Slog.i(TAG, "Window Manager"); wm = WindowManagerService.main(context, power, display, inputManager, wmHandler, factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL, !firstBoot, onlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); ActivityManagerService.self().setWindowManager(wm); inputManager.setWindowManagerCallbacks(wm.getInputMonitor()); inputManager.start();
首行便是初始化一个InputManagerService的实例,
public InputManagerService(Context context, Handler handler) { this.mContext = context; this.mHandler = new InputManagerHandler(handler.getLooper()); mUseDevInputEventForAudioJack = context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack); Slog.i(TAG, "Initializing input manager, mUseDevInputEventForAudioJack=" + mUseDevInputEventForAudioJack); mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue()); }
nativeInit方法:
static jint 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<jint>(im); }
代码段如下:
NativeInputManager::NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper) : mLooper(looper) { 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; } sp<EventHub> eventHub = new EventHub(); mInputManager = new InputManager(eventHub, this, this); }
初始化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); #ifdef USE_POWER_HINT_INPUT_BOOST mMonitor = new PhsInputMonitor(eventHub, readerPolicy); #endif initialize(); }
initialize()方法,初始化两个线程,InputReader和InputDispatcher等,
void InputManager::initialize() { mReaderThread = new InputReaderThread(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher); }
回到一开始的代码段的紫色行,代码调用了inputManager的start()方法:
public void start() { Slog.i(TAG, "Starting input manager"); nativeStart(mPtr); // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); registerPointerSpeedSettingObserver(); registerShowTouchesSettingObserver(); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); } }, new IntentFilter(Intent.ACTION_USER_SWITCHED), null, mHandler); updatePointerSpeedFromSettings(); updateShowTouchesFromSettings(); }
红色标注的代码段是关键,
static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); status_t result = im->getInputManager()->start(); if (result) { jniThrowRuntimeException(env, "Input manager could not be started."); } }
调用至InputManager的start()方法;
status_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; } #ifdef USE_POWER_HINT_INPUT_BOOST mMonitor->startMonitor(); #endif return OK; }
末段,开启了上边提到的两个关键线程,mDispatcherThread和mReaderThread,后面继续分析input子系统在上层的这两个关键线程:大体流程就是ReaderThread通过EventHub获取kernel上报的input事件,唤醒DispatherThread去处理相关input事件,Dispatcher根据事件的类型以及有效性做一个判断,从而决定事件发送不发送,发送给谁等。详细的方法调用流程,后面的文章会做分析。。。先告一段落!
相关文章推荐
- 【Android笔记】各个屏幕的logo尺寸要求
- Android插入物理键盘的同时显示软键盘
- Android2.2 API —— ImageView
- 百度云推送消息到达率低问题定位分析
- Android内存泄露案例分析
- android:tint
- Android --ListView模板
- Vysor 在电脑上控制android手机屏幕 镜像
- Android开发之使用viewpager实现图片轮播(二)
- ANDROID 工程导入报 NO RESOURCE FOUND 一类编译错误的解决
- android API Demos 路径
- 【转】 Android 各种常规图标尺寸
- Android apk动态加载机制的研究(二):资源加载和activity生命周期管理
- android Telephony结构
- 解决Android中xml文件Graphical Layout显示和真机运行显示不相同问题
- Android最佳性能实践(一)——合理管理内存
- android——Fragment与Activity
- Android处理图片OOM的若干方法小结
- android textView 删除线的使用
- android工程添加第三方库.so文件