Android 입력 이벤트 프로 세 스 모음 집
전재 할 때 출처 와 작가 의 연락 처 를 밝 혀 주 십시오.
글 의 출처:http://www.limodev.cn/blog저자 연락처: 이선 정 < xianjimli at hotmail dot com >
EventHub 는 입력 장 치 를 봉인 했다.장치 드라이버 를 입력 하여 사용자 공간 프로그램 에 장치 파일 을 제공 합 니 다. 이 장치 파일 들 은 / dev / input 에 넣 습 니 다.
EventHub 에서 모든 장치 파일 을 검색 하고 엽 니 다.
bool EventHub::openPlatformInput(void)
{
...
mFDCount = 1;
mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
mFDs[0].events = POLLIN;
mDevices[0] = NULL;
res = scan_dir(device_path);
...
return true;
}
EventHub 는 입력 장치 파일 에서 데 이 터 를 읽 을 수 있 는 함 수 를 제공 합 니 다.
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
int32_t* outValue, nsecs_t* outWhen)
{
...
while(1) {
// First, report any devices that had last been added/removed.
if (mClosingDevices != NULL) {
device_t* device = mClosingDevices;
LOGV("Reporting device closed: id=0x%x, name=%s/n",
device->id, device->path.string());
mClosingDevices = device->next;
*outDeviceId = device->id;
if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
*outType = DEVICE_REMOVED;
delete device;
return true;
}
if (mOpeningDevices != NULL) {
device_t* device = mOpeningDevices;
LOGV("Reporting device opened: id=0x%x, name=%s/n",
device->id, device->path.string());
mOpeningDevices = device->next;
*outDeviceId = device->id;
if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
*outType = DEVICE_ADDED;
return true;
}
release_wake_lock(WAKE_LOCK_ID);
pollres = poll(mFDs, mFDCount, -1);
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
if (pollres <= 0) {
if (errno != EINTR) {
LOGW("select failed (errno=%d)/n", errno);
usleep(100000);
}
continue;
}
for(i = 1; i < mFDCount; i++) {
if(mFDs[i].revents) {
LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
if(mFDs[i].revents & POLLIN) {
res = read(mFDs[i].fd, &iev, sizeof(iev));
if (res == sizeof(iev)) {
LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
mDevices[i]->path.string(),
(int) iev.time.tv_sec, (int) iev.time.tv_usec,
iev.type, iev.code, iev.value);
*outDeviceId = mDevices[i]->id;
if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
*outType = iev.type;
*outScancode = iev.code;
if (iev.type == EV_KEY) {
err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d/n",
iev.code, *outKeycode, *outFlags, err);
if (err != 0) {
*outKeycode = 0;
*outFlags = 0;
}
} else {
*outKeycode = iev.code;
}
*outValue = iev.value;
*outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
return true;
} else {
if (res<0) {
LOGW("could not get event (errno=%d)", errno);
} else {
LOGE("could not get event (wrong size: %d)", res);
}
continue;
}
}
}
}
...
}
버튼 이벤트 에 대해 mDevices [i] - > layotMap - > map 를 호출 하여 매 핑 합 니 다.맵 은 실제 KeyLayoutMap:: map 에서 이 루어 집 니 다. KeyLayoutMap 클래스 에서 설정 파일 qwerty. kl 을 읽 고 설정 파일 qwerty. kl 에서 키 값 의 맵 관 계 를 결정 합 니 다.키 값 의 맵 관 계 를 변경 할 수 있 습 니 다. / development / emulator / keymaps / qwerty. kl 을 수정 할 수 있 습 니 다.
JNI 함수
frameworks / base / services / jni / comandroid_server_KeyInputQueue. cpp 파일 에서 JAVA 에 함수 android 제공server_KeyInputQueue_readEvent, 입력 장치 이 벤트 를 읽 는 데 사 용 됩 니 다.
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 구조 로 전환 합 니 다.o 이벤트 중간 스 레 드
frameworks / base / services / java / com / android / server / KeyInputQueue. 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;
readEvent(ev);
send = preprocessEvent(di, ev);
addLocked(di, curTime, ev.flags, ..., me);
}
}
};
o 입력 이벤트 배포 스 레 드
frameworks / base / services / java / com / android / server / Window Manager Service. java 에 입력 이벤트 배포 스 레 드 를 만 들 었 습 니 다. 이 벤트 를 해당 창 에 배포 합 니 다.
mQueue.getEvent
dispatchKey/dispatchPointer/dispatchTrackball
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Exception in thread main java.lang. NoClassDefFoundError 오류 해결 방법즉,/home/hadoop/jarfile) 시스템은 Hello World 패키지 아래의class라는 클래스 파일을 실행하고 있다고 오인하여 시스템의 CLASSPATH 아래 (일반적으로 현재 디렉터리를 포함) Hell...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.