目录
1.事件从java层到JNI层的Looper
NativePreIme 收到的按键事件是由WindowInputEventReceiver的onInputEvent分发下来:
frameworks/base/core/java/android/view/ViewRootImpl.java
public void onInputEvent(InputEvent event) {
enqueueInputEvent(event, this, 0, true);
}
然后经doProcessInputEvents() 调用deliverInputEvent(q);
private void deliverInputEvent(QueuedInputEvent q) {
......
stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
......
stage.deliver(q);
}
当stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage = nativePreImeStage时,就正式进入它的deliver(q)函数:
public final void deliver(QueuedInputEvent q) {
if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) {
forward(q);
} else if (shouldDropInputEvent(q)) {
finish(q, false);
} else {
apply(q, onProcess(q));
}
}
然后调用它的onProcess():
protected int onProcess(QueuedInputEvent q) {
if (mInputQueue != null && q.mEvent instanceof KeyEvent) {
mInputQueue.sendInputEvent(q.mEvent, q, true, this);
return DEFER;
}
return FORWARD;
}
sendInputEvent会调用到jni文件:
frameworks/base/core/jni/android_view_InputQueue.cpp
static jlong nativeSendKeyEvent(JNIEnv* env, jobject clazz, jlong ptr, jobject eventObj,
jboolean predispatch) {
......
queue->enqueueEvent(event);
return reinterpret_cast<jlong>(event);
}
事件会通过queue->enqueueEvent(event); 放入一个队列中,然后调用write函数:
void InputQueue::enqueueEvent(InputEvent* event) {
Mutex::Autolock _l(mLock);
mPendingEvents.push(event);
if (mPendingEvents.size() == 1) {
char dummy = 0;
int res = TEMP_FAILURE_RETRY(write(mDispatchWriteFd, &dummy, sizeof(dummy)));
if (res < 0 && errno != EAGAIN) {
ALOGW("Failed writing to dispatch fd: %s", strerror(errno));
}
}
}
write函数会唤醒一个线程,事件的流转先放下,来研究下这个线程。
2.NativeActivity创建过程
使用NativeActivity的app在启动的时候会调用 framework/base/core/java/android/app/NativeActivity.java 它的onCreate
函数会调用loadNativeCode,它的实现在framework/base/core/jni/android_app_NativeActivity.cpp 文件中:
loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName,
jobject messageQueue, jstring internalDataDir, jstring obbDir,
jstring externalDataDir, jint sdkVersion,
jobject jAssetMgr, jbyteArray savedState)
{
......
void* handle = dlopen(pathStr, RTLD_LAZY);
......
if (handle != NULL) {
void* funcPtr = NULL;
const char* funcStr = env->GetStringUTFChars(funcName, NULL);
if (needNativeBridge) {
funcPtr = NativeBridgeGetTrampoline(handle, funcStr, NULL, 0);
} else {
funcPtr = dlsym(handle, funcStr);
}
......
code = new NativeCode(handle, (ANativeActivity_createFunc*)funcPtr);
env->ReleaseStringUTFChars(funcName, funcStr);
......
code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue);
int msgpipe[2];
.......
code->mainWorkRead = msgpipe[0];
code->mainWorkWrite = msgpipe[1];
int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK);
......
result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK);
......
code->messageQueue->getLooper()->addFd(
code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code);
code->ANativeActivity::callbacks = &code->callbacks;
......
code->createActivityFunc(code, rawSavedState, rawSavedSize);
......
}
return (jlong)code;
}
可以看到loadNativeCode_native加载本地的so文件,并创建一个管道,添加到looper的监控中,最后调用createActivityFunc,这个函数指针对应的so文件中的具体函数是由funcname参数指定的 String funcname = “ANativeActivity_onCreate” 所以最终调用了ANativeActivity_onCreate函数:
development/ndk/sources/android/native_app_glue/android_native_app_glue.c
void ANativeActivity_onCreate(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
......
activity->instance = android_app_create(activity, savedState, savedStateSize);
}
static struct android_app* android_app_create(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
......
int msgpipe[2];
if (pipe(msgpipe)) {
LOGE("could not create pipe: %s", strerror(errno));
return NULL;
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
......
pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
......
}
android_app_create 创建了一个管道和一个线程,并启动了线程,android_app_entry开始执行: