Android事件处理分析


按键事件

对于按键事件,调用mDevices->layoutMap->map进行映射。映射实际是由 KeyLayoutMap::map完成的,KeyLayoutMap类里读取配置文件qwerty.kl,由配置 文件 qwerty.kl 决定键值的映射关系。你可以通过修 改./development/emulator/keymaps/qwerty.kl来改变键值的映射关系。

JNI 函数

在 frameworks/base/services/jni/com_Android_server_KeyInputQueue.cpp文 件中,向 JAVA提供了函数android_server_KeyInputQueue_readEvent,用于读 取输入设备事件。

C代码:

static jboolean android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
                                           jobject event)
{
    gLock.lock();
    sp hub = gHub;
    if (hub == NULL) {
        hub = new EventHub;
        gHub = hub;
    }
    gLock.unlock();
    int32_t deviceId;
    int32_t type;
    int32_t scancode, keycode;
    uint32_t flags;
    int32_t value;
    nsecs_t when;
    bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,
            &flags, &value, &when);
    env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId);
    env->SetIntField(event, gInputOffsets.mType, (jint)type);
    env->SetIntField(event, gInputOffsets.mScancode, (jint)scancode);
    env->SetIntField(event, gInputOffsets.mKeycode, (jint)keycode);
    env->SetIntField(event, gInputOffsets.mFlags, (jint)flags);
    env->SetIntField(event, gInputOffsets.mValue, value);
    env->SetLongField(event, gInputOffsets.mWhen,
                       (jlong)(nanoseconds_to_milliseconds(when)));
    return res;
}

readEvent调用hub->getEvent读了取事件,然后转换成JAVA的结构。

事件中转线程

在frameworks/base/services/java/com/android/server/KeyInputQueue.java 里创建了一个线程,它循环的读取事件,然后把事件放入事件队列里。

Java代码:

Thread mThread = new Thread("InputDeviceReader") {
        public void run() {
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
           
            try {
                RawInputEvent ev = new RawInputEvent();
                while (true) {
                    InputDevice di;

                    // block, doesn't release the monitor
                    readEvent(ev);

                    boolean send = false;
                    boolean configChanged = false;
                   
                    if (false) {
                        Log.i(TAG, "Input event: dev=0x"
                                + Integer.toHexString(ev.deviceId)
                                + " type=0x" + Integer.toHexString(ev.type)
                                + " scancode=" + ev.scancode
                                + " keycode=" + ev.keycode
                                + " value=" + ev.value);
                    }
                   
                    if (ev.type == RawInputEvent.EV_DEVICE_ADDED) {
                        synchronized (mFirst) {
                            di = newInputDevice(ev.deviceId);
                            mDevices.put(ev.deviceId, di);
                            configChanged = true;
                        }
                    }

            ......
          }
        }
      }
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 下一页

相关内容