接某某公司的电话面试,聊着聊着对方来了句:
你知道事件是怎么传递到Activity的吗?
ps: 我在电话那头懵了?,一时语塞,难道是要造火箭?
基于android11源码进行分析
回到正题,不管造不造火箭,我们来看一下这个问题,这玩意:了解即可
我们在 Activity
内复写的 dispatchTouchEvent
方法中使用:
Thread.dumpStack()
打印当前线程的堆栈信息:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1523)
at com.melody.demo.MainActivity.dispatchTouchEvent(MainActivity.kt:31)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:679)
at android.view.View.dispatchPointerEvent(View.java:13961)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6402)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6197)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5586)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5639)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5605)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5763)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5613)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5820)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5586)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5639)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5605)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5613)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5586)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8680)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8600)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8553)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8938)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:239)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:363)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:8668)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
复制代码
我们参考上面的堆栈信息,从分析一下里面的源码:
注意:不要看行数,我们需要前后源码连起来看
1.ZygoteInit.main函数
main函数
为开篇入口:
//com.android.internal.os.ZygoteInit
public static void main(String argv[]) {
//统一用省略号代替部分代码...
...
try {
....
if (startSystemServer) {
//fork出子进程SystemServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
//caller.run()执行内部方法
//循环读取消息,获取子进程发送的消息
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
throw ex;
} finally {
...
}
if (caller != null) {
caller.run();
}
}
复制代码
我们根据:RuntimeInit$MethodAndArgsCaller.run
反向推导出来源是来自forkSystemServer
,继续看:
//com.android.internal.os.ZygoteInit
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
....
//使用硬编码的方式定义出启动system server的参数字符串args
String args[] = ...
ZygoteArguments parsedArgs = null;
try {
//zygote命令行参数,把args解析为需要的参数
parsedArgs = new ZygoteArguments(args);
...
//fork创建SystemServer
pid = Zygote.forkSystemServer(....);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
if (pid == 0) {//表示子进程执行
....
return handleSystemServerProcess(parsedArgs);
}
return null;
}
复制代码
接着奏乐接着舞,我们看下handleSystemServerProcess
做了什么?
//com.android.internal.os.ZygoteInit
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
....
if (parsedArgs.mInvokeWith != null) {
String[] args = parsedArgs.mRemainingArgs;
.....
//启动应用进程
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建类加载器
cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
//赋予当前线程
Thread.currentThread().setContextClassLoader(cl);
}
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
复制代码
我们看看 zygoteInit
里面做了什么事情:
//com.android.internal.os.ZygoteInit
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
....
//将System.out和System.err重定向到安卓日志。
RuntimeInit.redirectLogStreams();
//通用初始化:异常捕获、重置log配置、网络流量统计等
RuntimeInit.commonInit();
//不懂,哈哈哈
ZygoteInit.nativeZygoteInit();
//最终会进入ActivityThread 的 main 方法
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
复制代码
2.ActivityThread的main函数
走起,看看applicationInit
,又有什么小九九:
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
....
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
复制代码
看好了,小兄弟 findStaticMain:
//com.android.internal.os.RuntimeInit
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
//通过 className("android.app.ActivityThread" )反射得到 ActivityThread 类
//className 通过 AMS 等其它地方传递过来的,并不是唯一
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(....);
}
Method m;
try {
//拿到 ActivityThread的 main 函数
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(...);
} catch (SecurityException ex) {
throw new RuntimeException(...);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(...);
}
return new MethodAndArgsCaller(m, argv);
}
static class MethodAndArgsCaller implements Runnable {
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
//开始执行 ActivityThread的main 方法
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
复制代码
到此,我们才发现,刚刚执行到 RuntimeInit$MethodAndArgsCaller.run
,里面将会通过invoke
执行 ActivityThread.main(args)
3.InputEventReceiver.dispatchInputEvent
我们在文章一开始打印的堆栈信息的时候,能看到执行的顺序是:
Looper.loop() -> Message.getNext() -> nativePollOnce(ptr,nextPollTimeoutMillis)
-> InputEventReceiver.dispatchInputEvent
复制代码
3.1 Looper.nativePollOnce
点击查看 android_os_MessageQueue.cpp 源码
//frameworks/base/core/jni/android_os_MessageQueue.cpp
//部分实现
static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
jlong ptr, jint timeoutMillis) {
NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}
复制代码
Java
层的MessageQueue
对应Native
层的NativeMessageQueue
void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
mPollEnv = env;
mPollObj = pollObj;
//调用了Native Looper的pollOnce()
mLooper->pollOnce(timeoutMillis);
mPollObj = NULL;
mPollEnv = NULL;
...
}
复制代码
//system/core/libutils/Looper.cpp
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
int result = 0;
for (;;) {
...
result = pollInner(timeoutMillis);
}
}
//喜欢看更多细节的,可以点击上面的链接自己查看源码
int Looper::pollInner(int timeoutMillis) {
struct epoll_event eventItems[EPOLL_MAX_EVENTS];
// 阻塞等待epoll返回事件,然后再处理Message和fd event
int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
...
for (int i = 0; i < eventCount; i++) {
//处理每一个读取到的event
int fd = eventItems[i].data.fd;
uint32_t epollEvents = eventItems[i].events;
...
ssize_t requestIndex = mRequests.indexOfKey(fd);
...
//处理request,生成对应的reponse对象,push到mResponses数组
pushResponse(events, mRequests.valueAt(requestIndex));
}
Done: ;
....
// Invoke all response callbacks.
for (size_t i = 0; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if (response.request.ident == POLL_CALLBACK) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
//大家注意了,注意此处的handleEvent,往下翻有解释
int callbackResult = response.request.callback->handleEvent(fd, events, data);
...
result = POLL_CALLBACK;
}
}
return result;
}
// Looper在阻塞的时候,可以通过wake()方法来唤醒它,
// 通过往mWakeEventFd写入"1",会导致epoll_wait返回,从而取消轮询状态。
void Looper::wake() {
uint64_t inc = 1;
/*
* 向mWakeEventFd写入数据,用于唤醒消息队列
* 调用这个方法后, epoll_wait函数会返回,沿着调用链一路向上
* pollInner->pollOnce->pollOnce->android_os_MessageQueue_nativePollOnce->nativePollOnce->next
* 此时Looper.loop()调用的next()会返回,循环体继续执行
*/
ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd.get(), &inc, sizeof(uint64_t)));
}
复制代码
3.2 callback->handleEvent
看一下response.request.callback->handleEvent(fd, events, data)
//system/core/libutils/Looper.cpp
SimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) :
mCallback(callback) {
}
????
int SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
return mCallback(fd, events, data);
}
复制代码
源码到此处的话,就感觉断了一样, 那么到底怎么触发InputEventReceiver.dispatchInputEvent的呢?
我们只能从InputEvent下手了,我们知道Android中有个叫 InputManagerService的类,怎么创建出来的?
大家可以去看一下SystemServer.java 代码
3.3 SystemServer
//com.android.server.SystemServer
public final class SystemServer{
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
....
//创建InputManagerService
//交给ServiceManager管理
//绑定WMS的InputManagerCallback
//执行inputMagerService.start()
startOtherServices(t);
}
}
复制代码
3.4 new InputManagerService
构造函数内会调用:nativeInit(), 初始化Native层的InputManagerService:
点击查看 InputManagerService.cpp 源码
//frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
...
//NativeInputManager 内部创建了【InputManager】,感兴趣的自行查看源码学习
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
messageQueue->getLooper());
im->incStrong(0);
return reinterpret_cast<jlong>(im);
}
复制代码
接着看InputManager里面初始了什么?
点击查看 InputManager 源码
//platform/frameworks/native/services/inputflinger/InputManager.cpp
InputManager::InputManager(
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
//初始化InputDispatcher
mDispatcher = createInputDispatcher(dispatcherPolicy);
//初始化InputReader
mReader = createInputReader(readerPolicy, mClassifier);
}
复制代码
SystemServer的main函数里面执行了 InputManagerService.start()
//platform/frameworks/native/services/inputflinger/InputManager.cpp
status_t InputManager::start() {
//InputDispatcher.start()
status_t result = mDispatcher->start();
if (result) {
return result;
}
//InputReader.start()
result = mReader->start();
if (result) {
//InputDispatcher.stop()
mDispatcher->stop();
return result;
}
return OK;
}
复制代码
//frameworks/native/services/inputflinger/InputDispatcher.cpp
status_t InputDispatcher::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
return OK;
}
复制代码
//platform/frameworks/native/services/inputflinger/reader/InputReader.cpp
status_t InputReader::start() {
if (mThread) {
return ALREADY_EXISTS;
}
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}
复制代码
代码看到这里,并不清楚后面会往哪走,发现一个新的玩意点击查看 EventHub.cpp 源码
好家伙,感觉做系统层开发的太苦逼了,好多东西?
