源码分析 | 事件是怎么传递到Activity的?看不懂,请叫上渣渣辉一起来啃我

接某某公司的电话面试,聊着聊着对方来了句:
你知道事件是怎么传递到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;
    ...
}
复制代码

点击查看 Looper.cpp源码

//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;
}
复制代码

点击查看 InputDispatcher.cpp 源码

//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;
}
复制代码

点击查看 InputReader.cpp 源码

//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 源码
好家伙,感觉做系统层开发的太苦逼了,好多东西?

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享