每一个应用程序都有一个ActivityThread,当这个应用的进程创建时,
会进入到ActivityThread的main函数运行
public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }这里Looper.prepareMainLooper()创建了mainLooper,并且Looper.loop() 进入loop循环,之后所有系统回调事件(比如onCreate)都通过这个looper接受 并由sMainThreadHandler这个主UI线程handler进行处理 thread.getHandler()返回的是final H mH = new H(); 当mH接受到LAUNCH_ACTIVITY事件之后, 调用handleLaunchActivity() > performLaunchActivity > onCreate framework/base/core/java/android/app/NativeActivity.java: 可以看到在onCreate()函数里做了很多动作,包括: takeSurface、takeInputQueue(表示用户自己来处理input事件, android不会调用java层的dispatch等函数), 设置NativeContentView,加载jni library, loadNativeCode返回的mNativeHandle对应着native层的ANativeActivity* activity, 在后继调用中会被传给native层,可以看到funcname对应着ANativeActivity_onCreate, ANativeActivity_onCreate会被自动调用
@Override protected void onCreate(Bundle savedInstanceState) { String libname = "main"; String funcname = "ANativeActivity_onCreate"; ActivityInfo ai; mIMM = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); getWindow().takeSurface(this); getWindow().takeInputQueue(this); getWindow().setFormat(PixelFormat.RGB_565); getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); mNativeContentView = new NativeContentView(this); mNativeContentView.mActivity = this; setContentView(mNativeContentView); mNativeContentView.requestFocus(); mNativeContentView.getViewTreeObserver().addOnGlobalLayoutListener(this); try { ai = getPackageManager().getActivityInfo( getIntent().getComponent(), PackageManager.GET_META_DATA); if (ai.metaData != null) { String ln = ai.metaData.getString(META_DATA_LIB_NAME); if (ln != null) libname = ln; ln = ai.metaData.getString(META_DATA_FUNC_NAME); if (ln != null) funcname = ln; } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException("Error getting activity info", e); } String path = null; File libraryFile = new File(ai.applicationInfo.nativeLibraryDir, System.mapLibraryName(libname)); if (libraryFile.exists()) { path = libraryFile.getPath(); } if (path == null) { throw new IllegalArgumentException("Unable to find native library: " + libname); } byte[] nativeSavedState = savedInstanceState != null ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null; mNativeHandle = loadNativeCode(path, funcname, Looper.myQueue(), getAbsolutePath(getFilesDir()), getAbsolutePath(getObbDir()), getAbsolutePath(getExternalFilesDir(null)), Build.VERSION.SDK_INT, getAssets(), nativeSavedState); if (mNativeHandle == 0) { throw new IllegalArgumentException("Unable to load native library: " + path); } super.onCreate(savedInstanceState); }
loadNativeCode调用jni层的loadNativeCode_native
它通过java层的messageQueue取得对应的native层的messageQueue,并赋值给code->messageQueue
创建pipe,将读端赋值给code->mainWorkRead,写端赋值给code->mainWorkWrite
并将读端添加到主线程looper中进行监听,对应的回调函数是mainWorkCallback
这里创建的pipe主要用于将native层函数调用传递到java层
例如由native层发起android_NativeActivity_showSoftInput,它就向
code->mainWorkWrite写入CMD_SHOW_SOFT_INPUT,唤醒looper并进入mainWorkCallback回调
case CMD_SHOW_SOFT_INPUT: { code->env->CallVoidMethod(code->clazz, gNativeActivityClassInfo.showIme, work.arg1); code->messageQueue->raiseAndClearException(code->env, "showIme"); } break;进而调用java层的showIme() 设置好code struct其他字段后,code->createActivityFunc调用jni层的ANativeActivity_onCreate code对应于ANativeActivity结构体,load结束后保存在java层的mNativeHandle变量中 frameworks/base/core/jni/android_app_NativeActivity.cpp > loadNativeCode_native
static jint loadNativeCode_native(JNIEnv* env, jobject clazz, jstring path, jstring funcName, jobject messageQueue, jstring internalDataDir, jstring obbDir, jstring externalDataDir, int sdkVersion, jobject jAssetMgr, jbyteArray savedState) { LOG_TRACE("loadNativeCode_native"); const char* pathStr = env->GetStringUTFChars(path, NULL); NativeCode* code = NULL; void* handle = dlopen(pathStr, RTLD_LAZY); env->ReleaseStringUTFChars(path, pathStr); if (handle != NULL) { const char* funcStr = env->GetStringUTFChars(funcName, NULL); code = new NativeCode(handle, (ANativeActivity_createFunc*) dlsym(handle, funcStr)); env->ReleaseStringUTFChars(funcName, funcStr); if (code->createActivityFunc == NULL) { ALOGW("ANativeActivity_onCreate not found"); delete code; return 0; } code->messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueue); if (code->messageQueue == NULL) { ALOGW("Unable to retrieve native MessageQueue"); delete code; return 0; } int msgpipe[2]; if (pipe(msgpipe)) { ALOGW("could not create pipe: %s", strerror(errno)); delete code; return 0; } code->mainWorkRead = msgpipe[0]; code->mainWorkWrite = msgpipe[1]; int result = fcntl(code->mainWorkRead, F_SETFL, O_NONBLOCK); SLOGW_IF(result != 0, "Could not make main work read pipe " "non-blocking: %s", strerror(errno)); result = fcntl(code->mainWorkWrite, F_SETFL, O_NONBLOCK); SLOGW_IF(result != 0, "Could not make main work write pipe " "non-blocking: %s", strerror(errno)); code->messageQueue->getLooper()->addFd( code->mainWorkRead, 0, ALOOPER_EVENT_INPUT, mainWorkCallback, code); code->ANativeActivity::callbacks = &code->callbacks; if (env->GetJavaVM(&code->vm) < 0) { ALOGW("NativeActivity GetJavaVM failed"); delete code; return 0; } code->env = env; code->clazz = env->NewGlobalRef(clazz); const char* dirStr = env->GetStringUTFChars(internalDataDir, NULL); code->internalDataPathObj = dirStr; code->internalDataPath = code->internalDataPathObj.string(); env->ReleaseStringUTFChars(internalDataDir, dirStr); if (externalDataDir != NULL) { dirStr = env->GetStringUTFChars(externalDataDir, NULL); code->externalDataPathObj = dirStr; env->ReleaseStringUTFChars(externalDataDir, dirStr); } code->externalDataPath = code->externalDataPathObj.string(); code->sdkVersion = sdkVersion; code->assetManager = assetManagerForJavaObject(env, jAssetMgr); if (obbDir != NULL) { dirStr = env->GetStringUTFChars(obbDir, NULL); code->obbPathObj = dirStr; env->ReleaseStringUTFChars(obbDir, dirStr); } code->obbPath = code->obbPathObj.string(); jbyte* rawSavedState = NULL; jsize rawSavedSize = 0; if (savedState != NULL) { rawSavedState = env->GetByteArrayElements(savedState, NULL); rawSavedSize = env->GetArrayLength(savedState); } code->createActivityFunc(code, rawSavedState, rawSavedSize); if (rawSavedState != NULL) { env->ReleaseByteArrayElements(savedState, rawSavedState, 0); } } return (jint)code; }
在NDK中android-ndk-r9d/sources/android/native_app_glue/android_native_app_glue.c
ANativeActivity_onCreate的实现为:
void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) { LOGV("Creating: %p\n", activity); activity->callbacks->onDestroy = onDestroy; activity->callbacks->onStart = onStart; activity->callbacks->onResume = onResume; activity->callbacks->onSaveInstanceState = onSaveInstanceState; activity->callbacks->onPause = onPause; activity->callbacks->onStop = onStop; activity->callbacks->onConfigurationChanged = onConfigurationChanged; activity->callbacks->onLowMemory = onLowMemory; activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; activity->callbacks->onInputQueueCreated = onInputQueueCreated; activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; activity->instance = android_app_create(activity, savedState, savedStateSize); }可以看到设置了一些callbacks,包括常见的onResume、onPause等, onInputQueueCreated也是在这里设置的,后面会看到 最后调用android_app_create,
static struct android_app* android_app_create(ANativeActivity* activity, void* savedState, size_t savedStateSize) { struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); memset(android_app, 0, sizeof(struct android_app)); android_app->activity = activity; pthread_mutex_init(&android_app->mutex, NULL); pthread_cond_init(&android_app->cond, NULL); if (savedState != NULL) { android_app->savedState = malloc(savedStateSize); android_app->savedStateSize = savedStateSize; memcpy(android_app->savedState, savedState, 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_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&android_app->thread, &attr, android_app_entry, android_app); // Wait for thread to start. pthread_mutex_lock(&android_app->mutex); while (!android_app->running) { pthread_cond_wait(&android_app->cond, &android_app->mutex); } pthread_mutex_unlock(&android_app->mutex); return android_app; }这个函数会malloc一个struct android_app的自定义结构体保存一些必要的变量, pipe(msgpipe)创建一个pipe管道,接着pthread_create创建子线程, 子线程的入口是android_app_entry,等待子线程起来后就可以返回了, 返回的android_app结构体保存在ANativeActivity的instance,它是一个 void*指针,可以保存任何用户自定义数据,这里是android_app结构体 回到android_app_entry这个子线程入口:
static void* android_app_entry(void* param) { struct android_app* android_app = (struct android_app*)param; android_app->config = AConfiguration_new(); AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); print_cur_config(android_app); android_app->cmdPollSource.id = LOOPER_ID_MAIN; android_app->cmdPollSource.app = android_app; android_app->cmdPollSource.process = process_cmd; android_app->inputPollSource.id = LOOPER_ID_INPUT; android_app->inputPollSource.app = android_app; android_app->inputPollSource.process = process_input; ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, &android_app->cmdPollSource); android_app->looper = looper; pthread_mutex_lock(&android_app->mutex); android_app->running = 1; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); android_main(android_app); android_app_destroy(android_app); return NULL; }这里创建一个native层的looper ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); 关于looper更详细的介绍可以参考《Android应用程序消息处理机制(Looper、Handler)分析》(下载) 然后将前面pipe创建的msgread读端FD,挂到这个looper去监听, int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) fd对应android_app->msgread,ident对应LOOPER_ID_MAIN,events对应ALOOPER_EVENT_INPUT(监听输入事件), callback为NULL,data指向&android_app->cmdPollSource 一旦pipe的写端msgwrite写入了数据,监听msgread的looper就会被唤醒(pollOnce结束block状态), 对于传入callback为NULL的情况,pollOnce直接返回ident,根据这个值就知道是什么类型的事件了, 比如LOOPER_ID_MAIN、LOOPER_ID_INPUT等等,参考前一篇《retroarch:启动入口、android输入驱动》 中process_events调用android_run_events时的ALooper_pollOnce 这里我们传进去的是LOOPER_ID_MAIN,表明是android系统相关的事件 注意,这里创建的pipe及looper是在一个新线程中运行的,而不是前面的主UI线程 后面提到的LOOPER_ID_MAIN、LOOPER_ID_INPUT都是在这个新线程中处理的 下面来看看跟Looper相关的部分: ALooper_xxx函数基本上都是将调用传递给looper frameworks/base/native/android/looper.cpp
ALooper* ALooper_forThread() { return Looper::getForThread().get(); } ALooper* ALooper_prepare(int opts) { return Looper::prepare(opts).get(); } int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { sp looper = Looper::getForThread(); if (looper == NULL) { ALOGE("ALooper_pollOnce: No looper for this thread!"); return ALOOPER_POLL_ERROR; } IPCThreadState::self()->flushCommands(); return looper->pollOnce(timeoutMillis, outFd, outEvents, outData); } int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { sp looper = Looper::getForThread(); if (looper == NULL) { ALOGE("ALooper_pollAll: No looper for this thread!"); return ALOOPER_POLL_ERROR; } IPCThreadState::self()->flushCommands(); return looper->pollAll(timeoutMillis, outFd, outEvents, outData); } void ALooper_wake(ALooper* looper) { static_cast<Looper*>(looper)->wake(); } int ALooper_addFd(ALooper* looper, int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { return static_cast<Looper*>(looper)->addFd(fd, ident, events, callback, data); } int ALooper_removeFd(ALooper* looper, int fd) { return static_cast<Looper*>(looper)->removeFd(fd); }关于looper可以参考android源代码目录下的system/core/libutils/Looper.cpp实现
sp Looper::prepare(int opts) { bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS; sp looper = Looper::getForThread(); if (looper == NULL) { looper = new Looper(allowNonCallbacks); Looper::setForThread(looper); } if (looper->getAllowNonCallbacks() != allowNonCallbacks) { ALOGW("Looper already prepared for this thread with a different value for the " "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); } return looper; } Looper::Looper(bool allowNonCallbacks) : mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { int wakeFds[2]; int result = pipe(wakeFds); LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); mWakeReadPipeFd = wakeFds[0]; mWakeWritePipeFd = wakeFds[1]; result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", errno); result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", errno); mIdling = false; // Allocate the epoll instance and register the wake pipe. mEpollFd = epoll_create(EPOLL_SIZE_HINT); LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); struct epoll_event eventItem; memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union eventItem.events = EPOLLIN; eventItem.data.fd = mWakeReadPipeFd; result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", errno); } int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { int result = 0; for (;;) { while (mResponseIndex < mResponses.size()) { const Response& response = mResponses.itemAt(mResponseIndex++); int ident = response.request.ident; if (ident >= 0) { int fd = response.request.fd; int events = response.events; void* data = response.request.data; #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - returning signalled identifier %d: " "fd=%d, events=0x%x, data=%p", this, ident, fd, events, data); #endif if (outFd != NULL) *outFd = fd; if (outEvents != NULL) *outEvents = events; if (outData != NULL) *outData = data; return ident; } } if (result != 0) { #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - returning result %d", this, result); #endif if (outFd != NULL) *outFd = 0; if (outEvents != NULL) *outEvents = 0; if (outData != NULL) *outData = NULL; return result; } result = pollInner(timeoutMillis); } } int Looper::pollInner(int timeoutMillis) { #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); #endif // Adjust the timeout based on when the next message is due. if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); if (messageTimeoutMillis >= 0 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { timeoutMillis = messageTimeoutMillis; } #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", this, mNextMessageUptime - now, timeoutMillis); #endif } // Poll. int result = ALOOPER_POLL_WAKE; mResponses.clear(); mResponseIndex = 0; // We are about to idle. mIdling = true; struct epoll_event eventItems[EPOLL_MAX_EVENTS]; int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); // No longer idling. mIdling = false; // Acquire lock. mLock.lock(); // Check for poll error. if (eventCount < 0) { if (errno == EINTR) { goto Done; } ALOGW("Poll failed with an unexpected error, errno=%d", errno); result = ALOOPER_POLL_ERROR; goto Done; } // Check for poll timeout. if (eventCount == 0) { #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - timeout", this); #endif result = ALOOPER_POLL_TIMEOUT; goto Done; } // Handle all events. #if DEBUG_POLL_AND_WAKE ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); #endif for (int i = 0; i < eventCount; i++) { int fd = eventItems[i].data.fd; uint32_t epollEvents = eventItems[i].events; if (fd == mWakeReadPipeFd) { if (epollEvents & EPOLLIN) { awoken(); } else { ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); } } else { ssize_t requestIndex = mRequests.indexOfKey(fd); if (requestIndex >= 0) { int events = 0; if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; pushResponse(events, mRequests.valueAt(requestIndex)); } else { ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " "no longer registered.", epollEvents, fd); } } } Done: ; // Invoke pending message callbacks. mNextMessageUptime = LLONG_MAX; while (mMessageEnvelopes.size() != 0) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); if (messageEnvelope.uptime <= now) { // Remove the envelope from the list. // We keep a strong reference to the handler until the call to handleMessage // finishes. Then we drop it so that the handler can be deleted *before* // we reacquire our lock. { // obtain handler sp<MessageHandler> handler = messageEnvelope.handler; Message message = messageEnvelope.message; mMessageEnvelopes.removeAt(0); mSendingMessage = true; mLock.unlock(); #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", this, handler.get(), message.what); #endif handler->handleMessage(message); } // release handler mLock.lock(); mSendingMessage = false; result = ALOOPER_POLL_CALLBACK; } else { // The last message left at the head of the queue determines the next wakeup time. mNextMessageUptime = messageEnvelope.uptime; break; } } // Release lock. mLock.unlock(); // Invoke all response callbacks. for (size_t i = 0; i < mResponses.size(); i++) { Response& response = mResponses.editItemAt(i); if (response.request.ident == ALOOPER_POLL_CALLBACK) { int fd = response.request.fd; int events = response.events; void* data = response.request.data; #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", this, response.request.callback.get(), fd, events, data); #endif int callbackResult = response.request.callback->handleEvent(fd, events, data); if (callbackResult == 0) { removeFd(fd); } // Clear the callback reference in the response structure promptly because we // will not clear the response vector itself until the next poll. response.request.callback.clear(); result = ALOOPER_POLL_CALLBACK; } } return result; } int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { if (timeoutMillis <= 0) { int result; do { result = pollOnce(timeoutMillis, outFd, outEvents, outData); } while (result == ALOOPER_POLL_CALLBACK); return result; } else { nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) + milliseconds_to_nanoseconds(timeoutMillis); for (;;) { int result = pollOnce(timeoutMillis, outFd, outEvents, outData); if (result != ALOOPER_POLL_CALLBACK) { return result; } nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); timeoutMillis = toMillisecondTimeoutDelay(now, endTime); if (timeoutMillis == 0) { return ALOOPER_POLL_TIMEOUT; } } } } void Looper::wake() { ssize_t nWrite; do { nWrite = write(mWakeWritePipeFd, "W", 1); } while (nWrite == -1 && errno == EINTR); if (nWrite != 1) { if (errno != EAGAIN) { ALOGW("Could not write wake signal, errno=%d", errno); } } } void Looper::awoken() { char buffer[16]; ssize_t nRead; do { nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); } int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); } int Looper::addFd(int fd, int ident, int events, const sp& callback, void* data) { if (!callback.get()) { if (! mAllowNonCallbacks) { ALOGE("Invalid attempt to set NULL callback but not allowed for this looper."); return -1; } if (ident < 0) { ALOGE("Invalid attempt to set NULL callback with ident < 0."); return -1; } } else { ident = ALOOPER_POLL_CALLBACK; } int epollEvents = 0; if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; { // acquire lock AutoMutex _l(mLock); Request request; request.fd = fd; request.ident = ident; request.callback = callback; request.data = data; struct epoll_event eventItem; memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union eventItem.events = epollEvents; eventItem.data.fd = fd; ssize_t requestIndex = mRequests.indexOfKey(fd); if (requestIndex < 0) { int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); if (epollResult < 0) { ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); return -1; } mRequests.add(fd, request); } else { int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); if (epollResult < 0) { ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); return -1; } mRequests.replaceValueAt(requestIndex, request); } } // release lock return 1; } void Looper::sendMessageAtTime(nsecs_t uptime, const sp& handler, const Message& message) { size_t i = 0; { // acquire lock AutoMutex _l(mLock); size_t messageCount = mMessageEnvelopes.size(); while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { i += 1; } MessageEnvelope messageEnvelope(uptime, handler, message); mMessageEnvelopes.insertAt(messageEnvelope, i, 1); // Optimization: If the Looper is currently sending a message, then we can skip // the call to wake() because the next thing the Looper will do after processing // messages is to decide when the next wakeup time should be. In fact, it does // not even matter whether this code is running on the Looper thread. if (mSendingMessage) { return; } } // release lock // Wake the poll loop only when we enqueue a new message at the head. if (i == 0) { wake(); } }最后android_main(android_app)进入主循环,android_main由app实现 可以看看NDK提供的sample native-activity实现:
void android_main(struct android_app* state) { struct engine engine; // Make sure glue isn't stripped. app_dummy(); memset(&engine, 0, sizeof(engine)); state->userData = &engine; state->onAppCmd = engine_handle_cmd; state->onInputEvent = engine_handle_input; engine.app = state; // Prepare to monitor accelerometer engine.sensorManager = ASensorManager_getInstance(); engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, ASENSOR_TYPE_ACCELEROMETER); engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, state->looper, LOOPER_ID_USER, NULL, NULL); if (state->savedState != NULL) { // We are starting with a previous saved state; restore from it. engine.state = *(struct saved_state*)state->savedState; } // loop waiting for stuff to do. while (1) { // Read all pending events. int ident; int events; struct android_poll_source* source; // If not animating, we will block forever waiting for events. // If animating, we loop until all events are read, then continue // to draw the next frame of animation. while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, (void**)&source)) >= 0) { // Process this event. if (source != NULL) { source->process(state, source); } // If a sensor has data, process it now. if (ident == LOOPER_ID_USER) { if (engine.accelerometerSensor != NULL) { ASensorEvent event; while (ASensorEventQueue_getEvents(engine.sensorEventQueue, &event, 1) > 0) { LOGI("accelerometer: x=%f y=%f z=%f", event.acceleration.x, event.acceleration.y, event.acceleration.z); } } } // Check if we are exiting. if (state->destroyRequested != 0) { engine_term_display(&engine); return; } } if (engine.animating) { // Done with events; draw next animation frame. engine.state.angle += .01f; if (engine.state.angle > 1) { engine.state.angle = 0; } // Drawing is throttled to the screen update rate, so there // is no need to do timing here. engine_draw_frame(&engine); } } } static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { engine->animating = 1; engine->state.x = AMotionEvent_getX(event, 0); engine->state.y = AMotionEvent_getY(event, 0); return 1; } return 0; }android_native_app_glue.c中,onInputQueueCreated被系统回调时,
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { LOGV("InputQueueCreated: %p -- %p\n", activity, queue); android_app_set_input((struct android_app*)activity->instance, queue); } static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { pthread_mutex_lock(&android_app->mutex); android_app->pendingInputQueue = inputQueue; android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); while (android_app->inputQueue != android_app->pendingInputQueue) { pthread_cond_wait(&android_app->cond, &android_app->mutex); } pthread_mutex_unlock(&android_app->mutex); }这里发送了一个APP_CMD_INPUT_CHANGED命令,
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); } }实际上就是向前面创建的pipe的写端msgwrite写入cmd,让挂在looper上等待的读端被唤醒, app在android_main循环中应该会不断调用looper的pollOnce/pollAll,这时就会返回LOOPER_ID_MAIN, 这时可以调用android_app->cmdPollSource中的process_cmd进行处理 process_cmd的实现如下:
static void process_cmd(struct android_app* app, struct android_poll_source* source) { int8_t cmd = android_app_read_cmd(app); android_app_pre_exec_cmd(app, cmd); if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); android_app_post_exec_cmd(app, cmd); } int8_t android_app_read_cmd(struct android_app* android_app) { int8_t cmd; if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { switch (cmd) { case APP_CMD_SAVE_STATE: free_saved_state(android_app); break; } return cmd; } else { LOGE("No data on command pipe!"); } return -1; }它会先调用android_app_pre_exec_cmd预处理一下,然后调用onAppCmd这个app实现的回调, 最后调用android_app_post_exec_cmd
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { switch (cmd) { case APP_CMD_INPUT_CHANGED: LOGV("APP_CMD_INPUT_CHANGED\n"); pthread_mutex_lock(&android_app->mutex); if (android_app->inputQueue != NULL) { AInputQueue_detachLooper(android_app->inputQueue); } android_app->inputQueue = android_app->pendingInputQueue; if (android_app->inputQueue != NULL) { LOGV("Attaching input queue to looper"); AInputQueue_attachLooper(android_app->inputQueue, android_app->looper, LOOPER_ID_INPUT, NULL, &android_app->inputPollSource); } pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); break; ....这里只看我们关心的APP_CMD_INPUT_CHANGED,主要执行了AInputQueue_attachLooper, frameworks/base/native/android/input.cpp:
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, int ident, ALooper_callbackFunc callback, void* data) { InputQueue* iq = static_cast<InputQueue*>(queue); Looper* l = static_cast<Looper*>(looper); iq->attachLooper(l, ident, callback, data); }frameworks/base/core/jni/android_view_InputQueue.cpp
void InputQueue::attachLooper(Looper* looper, int ident, ALooper_callbackFunc callback, void* data) { Mutex::Autolock _l(mLock); for (size_t i = 0; i < mAppLoopers.size(); i++) { if (looper == mAppLoopers[i]) { return; } } mAppLoopers.push(looper); looper->addFd(mDispatchReadFd, ident, ALOOPER_EVENT_INPUT, callback, data); }最终会调用looper的addFd,将mDispatchReadFd这个读端fd挂到looper上监听, 从mAppLoopers.push(looper)可以看到mDispatchReadFd可以有多个looper来监听, 至此,input queue的事件也被监听了,android系统底层向input queue的写端写入数据, 就能唤醒读端,而开发者通过pollOnce返回的ident为LOOPER_ID_INPUT 当LOOPER_ID_INPUT返回时,可以调用android_app->inputPollSource中的process_input进行处理 它会先调用AInputQueue_preDispatchEvent处理,接着调用app的onInputEvent, 最后调用AInputQueue_finishEvent结束处理
static void process_input(struct android_app* app, struct android_poll_source* source) { AInputEvent* event = NULL; while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { LOGV("New input event: type=%d\n", AInputEvent_getType(event)); if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { continue; } int32_t handled = 0; if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); AInputQueue_finishEvent(app->inputQueue, event, handled); } }
frameworks/base/native/android/input.cpp:
int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent) { InputQueue* iq = static_cast<InputQueue*>(queue); InputEvent* event; int32_t res = iq->getEvent(&event); *outEvent = event; return res; } int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event) { InputQueue* iq = static_cast<InputQueue*>(queue); InputEvent* e = static_cast<InputEvent*>(event); return iq->preDispatchEvent(e) ? 1 : 0; } void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled) { InputQueue* iq = static_cast<InputQueue*>(queue); InputEvent* e = static_cast<InputEvent*>(event); iq->finishEvent(e, handled != 0); }
frameworks/base/core/jni/android_view_InputQueue.cpp
status_t InputQueue::getEvent(InputEvent** outEvent) { Mutex::Autolock _l(mLock); *outEvent = NULL; if (!mPendingEvents.isEmpty()) { *outEvent = mPendingEvents[0]; mPendingEvents.removeAt(0); } if (mPendingEvents.isEmpty()) { char byteread[16]; ssize_t nRead; do { nRead = TEMP_FAILURE_RETRY(read(mDispatchReadFd, &byteread, sizeof(byteread))); if (nRead < 0 && errno != EAGAIN) { ALOGW("Failed to read from native dispatch pipe: %s", strerror(errno)); } } while (nRead > 0); } return *outEvent != NULL ? OK : WOULD_BLOCK; } bool InputQueue::preDispatchEvent(InputEvent* e) { if (e->getType() == AINPUT_EVENT_TYPE_KEY) { KeyEvent* keyEvent = static_cast<KeyEvent*>(e); if (keyEvent->getFlags() & AKEY_EVENT_FLAG_PREDISPATCH) { finishEvent(e, false); return true; } } return false; } void InputQueue::finishEvent(InputEvent* event, bool handled) { Mutex::Autolock _l(mLock); mFinishedEvents.push(key_value_pair_t<InputEvent*, bool>(event, handled)); if (mFinishedEvents.size() == 1) { mDispatchLooper->sendMessage(this, Message(MSG_FINISH_INPUT)); } }
再回到前面,android_native_app_glue.c中的onInputQueueCreated何时被回调的?
Java层在ViewRootImpl.java中调用setView时,会判断mInputQueueCallback是否为null,
对于NativeActivity,它在onCreate时调用了getWindow().takeInputQueue(this);
因此不为null,于是new InputQueue()创建一个InputQueue,
并且调用mInputQueueCallback.onInputQueueCreated
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { .... res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mInputChannel); .... if (mInputChannel != null) { if (mInputQueueCallback != null) { mInputQueue = new InputQueue(); mInputQueueCallback.onInputQueueCreated(mInputQueue); } mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper()); } .... }
new InputQueue()创建如下:
frameworks/base/core/java/android/view/InputQueue.java
public InputQueue() { mPtr = nativeInit(new WeakReference<InputQueue>(this), Looper.myQueue()); mCloseGuard.open("dispose"); }
frameworks/base/core/jni/android_view_InputQueue.cpp
static jint nativeInit(JNIEnv* env, jobject clazz, jobject queueWeak, jobject jMsgQueue) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, jMsgQueue); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); return 0; } sp<InputQueue> queue = InputQueue::createQueue(queueWeak, messageQueue->getLooper()); if (!queue.get()) { jniThrowRuntimeException(env, "InputQueue failed to initialize"); return 0; } queue->incStrong(&gInputQueueClassInfo); return reinterpret_cast<jint>(queue.get()); } InputQueue* InputQueue::createQueue(jobject inputQueueObj, const sp<Looper>& looper) { int pipeFds[2]; if (pipe(pipeFds)) { ALOGW("Could not create native input dispatching pipe: %s", strerror(errno)); return NULL; } fcntl(pipeFds[0], F_SETFL, O_NONBLOCK); fcntl(pipeFds[1], F_SETFL, O_NONBLOCK); return new InputQueue(inputQueueObj, looper, pipeFds[0], pipeFds[1]); } InputQueue::InputQueue(jobject inputQueueObj, const sp<Looper>& looper, int dispatchReadFd, int dispatchWriteFd) : mDispatchReadFd(dispatchReadFd), mDispatchWriteFd(dispatchWriteFd), mDispatchLooper(looper), mHandler(new WeakMessageHandler(this)) { JNIEnv* env = AndroidRuntime::getJNIEnv(); mInputQueueWeakGlobal = env->NewGlobalRef(inputQueueObj); }可以看到native层的InputQueue创建了一个pipe,读端是mDispatchReadFd 前面看到的InputQueue::attachLooper,就是将looper与这个读端绑定的 java层的onInputQueueCreated回调函数会调用native层: frameworks/base/core/java/android/view/InputQueue.java
public void onInputQueueCreated(InputQueue queue) { if (!mDestroyed) { mCurInputQueue = queue; onInputQueueCreatedNative(mNativeHandle, queue.getNativePtr()); } }frameworks/base/core/jni/android_app_NativeActivity.cpp:
static void onInputQueueCreated_native(JNIEnv* env, jobject clazz, jint handle, jint queuePtr) { LOG_TRACE("onInputChannelCreated_native"); if (handle != 0) { NativeCode* code = (NativeCode*)handle; if (code->callbacks.onInputQueueCreated != NULL) { AInputQueue* queue = reinterpret_cast<AInputQueue*>(queuePtr); code->callbacks.onInputQueueCreated(code, queue); } } }InputQueue中的另一个重要函数sendInputEvent, ViewRootImpl在收到InputEvent进行分发的流程中,会将InputEvent通过这个 函数插入到InputQueue中去,这样native层就接受到InputEvent了 可惜sendInputEvent是hide不可见的 可以看看native层是如何注入input event事件的(见nativeSendKeyEvent) frameworks/base/core/java/android/view/InputQueue.java
/** @hide */ public void sendInputEvent(InputEvent e, Object token, boolean predispatch, FinishedInputEventCallback callback) { ActiveInputEvent event = obtainActiveInputEvent(token, callback); int id; if (e instanceof KeyEvent) { id = nativeSendKeyEvent(mPtr, (KeyEvent) e, predispatch); } else { id = nativeSendMotionEvent(mPtr, (MotionEvent) e); } mActiveEventArray.put(id, event); } private void finishInputEvent(int id, boolean handled) { int index = mActiveEventArray.indexOfKey(id); if (index >= 0) { ActiveInputEvent e = mActiveEventArray.valueAt(index); mActiveEventArray.removeAt(index); e.mCallback.onFinishedInputEvent(e.mToken, handled); recycleActiveInputEvent(e); } }frameworks/base/core/jni/android_view_InputQueue.cpp
static jint nativeSendKeyEvent(JNIEnv* env, jobject clazz, jint ptr, jobject eventObj, jboolean predispatch) { InputQueue* queue = reinterpret_cast<InputQueue*>(ptr); KeyEvent* event = queue->createKeyEvent(); status_t status = android_view_KeyEvent_toNative(env, eventObj, event); if (status) { queue->recycleInputEvent(event); jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); return -1; } if (predispatch) { event->setFlags(event->getFlags() | AKEY_EVENT_FLAG_PREDISPATCH); } queue->enqueueEvent(event); return reinterpret_cast(event); } static jint nativeSendMotionEvent(JNIEnv* env, jobject clazz, jint ptr, jobject eventObj) { sp queue = reinterpret_cast<InputQueue*>(ptr); MotionEvent* originalEvent = android_view_MotionEvent_getNativePtr(env, eventObj); if (!originalEvent) { jniThrowRuntimeException(env, "Could not obtain MotionEvent pointer."); return -1; } MotionEvent* event = queue->createMotionEvent(); event->copyFrom(originalEvent, true /* keepHistory */); queue->enqueueEvent(event); return reinterpret_cast(event); }最后附上两个结构体的定义 ANativeActivity的定义如下:
typedef struct ANativeActivity { /** * Pointer to the callback function table of the native application. * You can set the functions here to your own callbacks. The callbacks * pointer itself here should not be changed; it is allocated and managed * for you by the framework. */ struct ANativeActivityCallbacks* callbacks; /** * The global handle on the process's Java VM. */ JavaVM* vm; /** * JNI context for the main thread of the app. Note that this field * can ONLY be used from the main thread of the process; that is, the * thread that calls into the ANativeActivityCallbacks. */ JNIEnv* env; /** * The NativeActivity object handle. * * IMPORTANT NOTE: This member is mis-named. It should really be named * 'activity' instead of 'clazz', since it's a reference to the * NativeActivity instance created by the system for you. * * We unfortunately cannot change this without breaking NDK * source-compatibility. */ jobject clazz; /** * Path to this application's internal data directory. */ const char* internalDataPath; /** * Path to this application's external (removable/mountable) data directory. */ const char* externalDataPath; /** * The platform's SDK version code. */ int32_t sdkVersion; /** * This is the native instance of the application. It is not used by * the framework, but can be set by the application to its own instance * state. */ void* instance; /** * Pointer to the Asset Manager instance for the application. The application * uses this to access binary assets bundled inside its own .apk file. */ AAssetManager* assetManager; } ANativeActivity;struct android_app的定义如下:
struct android_app { // The application can place a pointer to its own state object // here if it likes. void* userData; // Fill this in with the function to process main app commands (APP_CMD_*) void (*onAppCmd)(struct android_app* app, int32_t cmd); // Fill this in with the function to process input events. At this point // the event has already been pre-dispatched, and it will be finished upon // return. Return 1 if you have handled the event, 0 for any default // dispatching. int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); // The ANativeActivity object instance that this app is running in. ANativeActivity* activity; // The current configuration the app is running in. AConfiguration* config; // This is the last instance's saved state, as provided at creation time. // It is NULL if there was no state. You can use this as you need; the // memory will remain around until you call android_app_exec_cmd() for // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. // These variables should only be changed when processing a APP_CMD_SAVE_STATE, // at which point they will be initialized to NULL and you can malloc your // state and place the information here. In that case the memory will be // freed for you later. void* savedState; size_t savedStateSize; // The ALooper associated with the app's thread. ALooper* looper; // When non-NULL, this is the input queue from which the app will // receive user input events. AInputQueue* inputQueue; // When non-NULL, this is the window surface that the app can draw in. ANativeWindow* window; // Current content rectangle of the window; this is the area where the // window's content should be placed to be seen by the user. ARect contentRect; // Current state of the app's activity. May be either APP_CMD_START, // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. int activityState; // This is non-zero when the application's NativeActivity is being // destroyed and waiting for the app thread to complete. int destroyRequested; // ------------------------------------------------- // Below are "private" implementation of the glue code. pthread_mutex_t mutex; pthread_cond_t cond; int msgread; int msgwrite; pthread_t thread; struct android_poll_source cmdPollSource; struct android_poll_source inputPollSource; int running; int stateSaved; int destroyed; int redrawNeeded; AInputQueue* pendingInputQueue; ANativeWindow* pendingWindow; ARect pendingContentRect; };