https://gist.github.com/jieyu/4262418

https://gist.github.com/jieyu/4262418/raw/c1d0fc34eac41be55017ac6d8fc3b4b46cc7fe94/AndroidInputEventPropagation.md

# Android Input Event PropagationThis document discusses how an input event from user (e.g. user key stroke) is propagated in Android framework, and how it is delivered to the corresponding event handler in the application.This document is based on the code of Android 4.1.1_r6.1 (Jelly Bean).For each application, a `ViewRootImpl` object is created to handle communications with the remote system `WindowManagerService` object. The communication is through a Linux pipe which is encapsulated in an `InputChannel` object (`mInputChannel` field in class `ViewRootImpl`). The `ViewRootImpl` object also registers an instance of `InputEventReceiver` when the first `View` object is registered with it.    frameworks/base/core/java/android/view/ViewRootImpl.java +482    482  public void setView(View view, ...) {    ...    626    mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper());    ...    644  }The constructor of class `WindowInputEventReceiver` (class `WindowManagerService` extends from class `InputEventReceiver`) calls a native methond `nativeInit(...)`:    frameworks/base/core/java/android/view/InputEventReceiver.java +58    58   public InputEventReceiver(InputChannel inputChannel, Looper looper) {    ...    66     mInputChannel = inputChannel;    67     mMessageQueue = looper.getQueue();    68     mReceiverPtr = nativeInit(this, inputChannel, mMessageQueue);    ...    71   }Three parameters are passed to the native function `nativeInit`: 1) The receiver object itself; 2) The `InputChannel` object passed from the `ViewRootImpl` object. 3) The main message queue (an object of class `MessageQueue`) of the application.The native function `nativeInit` is shown as follows:    frameworks/base/core/jni/android_view_InputEventReceiver.cpp +227    227  static jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj,    228      jobject inputChannelObj, jobject messageQueueObj) {    229    sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,    230        inputChannelObj);    ...    236    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);    ...    242    sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,    243             receiverObj, inputChannel, messageQueue);    244    status_t status = receiver->initialize();    ...    254  }The function first gets a pointer to a `NativeInputChannel` object (line 229) and a pointer to a `NativeMessageQueue` object (line 236), then creates and initializes a `NativeInputEventReceiver` object (line 242-244) using these two pointers and the receiver object itself. In the `initialize()` function of class `NativeInputEventReceiver`, the file descriptor of the Linux pipe (which is passed from `ViewRootImpl` in the object of `InputChannel`) is sent to the looper for polling. When the file descriptor becomes readable which means the system `WindowManagerService` object has detected an input event from the kernel, a callback function will be invoked.    frameworks/base/core/jni/android_view_InputEventReceiver.cpp +92    92   status_t NativeInputEventReceiver::initialize() {    93     int receiveFd = mInputConsumer.getChannel()->getFd();    94     mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL);    95     return OK;    96   }The callback function is the `handleEvent(...)` function in the same class `NativeInputEventReceiver`:    frameworks/base/core/jni/android_view_InputEventReceiver.cpp +119    119  int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {    ...    132     JNIEnv* env = AndroidRuntime::getJNIEnv();    133     status_t status = consumeEvents(env, false /*consumeBatches*/, -1);    134     mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");    135     return status == OK || status == NO_MEMORY ? 1 : 0;    136  }    138  status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,    139      bool consumeBatches, nsecs_t frameTime) {    ...    187    inputEventObj = android_view_KeyEvent_fromNative(env,    188        static_cast<KeyEvent*>(inputEvent));    ...    208    env->CallVoidMethod(mReceiverObjGlobal,    209        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);    ...    224  }As shown above, function `handleEvent(...)` invokes a Java function `InputEventReceiver.dispatchInputEvent(...)` (line 208), which will eventually invoke `onInputEvent(...)` in class `WindowInputEventReceiver`:    frameworks/base/core/java/android/view/ViewRootImpl.java +4223    4223 public void onInputEvent(InputEvent event) {    4224   enqueueInputEvent(event, this, 0, true);    4225 }This function will eventually call `doProcessInputEvents()` (line 4147) which will then call `deliverInputEvent(...)` (line 3109) which will then call `deliverKeyEvent(...)` (line 3495). Finally, the event will be dispatch to the `View` object by calling `mView.dispatchKeyEvent(event)` (line 3575).Now, the question is how the system `WindowManagerService` object detects events from the kernel? It is actually quite simple, it polls several device files (e.g. /dev/input/eventX) exposed by the kernel. For more details, refer to this [blog](http://cjix.info/blog/misc/internal-input-event-handling-in-the-linux-kernel-and-the-android-userspace/).

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. 1.1LinearLayout
  2. Android 重构 | 持续优化统一管理 Gradle
  3. Android-TableLayout
  4. android虚线
  5. Android StrictMode介绍
  6. 通过OpenGL ES混合模式缩放视频缓冲区-An
  7. android shape+selector
  8. 图片旋转的两种方法
  9. android 实现调查问卷-单选-多选
  10. 【Android 电量优化】电量优化 ( 网络状