接某某公司的电话面试,聊着聊着对方来了句:
你知道事件是怎么传递到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 源码
好家伙,感觉做系统层开发的太苦逼了,好多东西🤔
//platform/frameworks/native/services/inputflinger/reader/EventHub.cpp
void EventHub::wake() {
ssize_t nWrite;
do {
//EventHub::getEvents方法中有这么一段代码:
//int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis)
//wake的时候往pipe的写端mWakeWritePipeFd写一字符"W"
//唤醒epoll_wait
nWrite = write(mWakeWritePipeFd, "W", 1);
} while (nWrite == -1 && errno == EINTR);
...
}
回到上面的loopOnce()
,执行了这个方法,才会执行EventHub::wake()
//platform/frameworks/native/services/inputflinger/reader/InputReader.cpp
void InputReader::loopOnce() {
...
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
{
mReaderIsAliveCondition.broadcast();
if (count) {
//处理事件
processEventsLocked(mEventBuffer, count);
}
...
}
...
mQueuedListener->flush();
}
void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
...
//数据事件的处理
processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
....
}
...
}
}
void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,size_t count) {
...
std::shared_ptr<InputDevice>& device = deviceIt->second;
device->process(rawEvents, count);
}
//platform/hardware/libhardware/modules/input/evdev/InputDevice.cpp
void InputDevice::process(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {
...
if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
mDropUntilNextSync = true;
reset(rawEvent->when);
} else {
for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
//调用具体InputMapper来处理
mapper.process(rawEvent);
});
}
--count;
}
}
mapper.process(event) 直接贴后面执行的一些方法
依次执行的顺序:
点击查看 TouchInputMapper.cpp 源码
//platform/frameworks/native/services/inputflinger/reader/mapper/TouchInputMapper.cpp
void TouchInputMapper::process(const RawEvent* rawEvent)
void TouchInputMapper::sync(nsecs_t when)
void TouchInputMapper::processRawTouches(bool timeout)
void TouchInputMapper::cookAndDispatch(nsecs_t when)
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags)
void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
int32_t action, int32_t actionButton, int32_t flags,...)
TouchInputMapper::dispatchMotion
方法最后会调用:
void TouchInputMapper::dispatchMotion(...){
...
getListener()->notifyMotion(&args);
}
getListener()实际上是InputDispatcher
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args)
好家伙,再回来看看InputDispatcher
,话说上面我们没有分析 InputDispatcher.start()
内部的dispatchOnce()
,细节方面感兴趣的可以自己去看源码,我们提供一下内部方法调用
的顺序:
//frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::dispatchOnce()
void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime)
bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, MotionEntry* entry,DropReason* dropReason, nsecs_t* nextWakeupTime)
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* eventEntry,const std::vector<InputTarget>& inputTargets)
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,const sp<Connection>& connection,EventEntry* eventEntry,const InputTarget& inputTarget)
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,const sp<Connection>& connection,EventEntry* eventEntry,const InputTarget& inputTarget)
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,const sp<Connection>& connection)
我们看最后一个方法startDispatchCycleLocked
:
//frameworks/native/services/inputflinger/InputDispatcher.cpp
void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,const sp<Connection>& connection) {
....
case EventEntry::Type::MOTION: {
....
// Publish the motion event.
status = connection->inputPublisher.publishMotionEvent(..)
....
}
}
InputPublisher
在哪儿呢?
谷歌了下,发现在这里 点击查看 InputTransport.cpp 源码
//frameworks/native/libs/input/InputTransport.cpp
status_t InputPublisher::publishMotionEvent(....) {
....
InputMessage msg;
msg.header.type = InputMessage::Type::MOTION;
....
msg.body.motion.downTime = downTime;
msg.body.motion.eventTime = eventTime;
msg.body.motion.pointerCount = pointerCount;
....
//进行跨进程通信
return mChannel->sendMessage(&msg);
}
不抛弃,不放弃,离真相越近,😂越心疼做framework开发的程序员👨💻
//frameworks/native/libs/input/InputTransport.cpp
//发送消息
status_t InputChannel::sendMessage(const InputMessage* msg) {
const size_t msgLength = msg->size();
InputMessage cleanMsg;
msg->getSanitizedCopy(&cleanMsg);
ssize_t nWrite;
do {
//写入Fd
nWrite = ::send(mFd.get(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
} while (nWrite == -1 && errno == EINTR);
...
return OK;
}
//接收消息
status_t InputChannel::receiveMessage(InputMessage* msg) {
ssize_t nRead;
do {
nRead = ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT);
} while (nRead == -1 && errno == EINTR);
...
return OK;
}
3.5 InputChannel在哪里创建的?
不知道有多少人能看到此处,我们在文章开始那里提示大家:
注意:不要看行数,我们需要前后源码连起来看
我们看这一行:ViewRootImpl$WindowInputEventReceiver.onInputEvent()
,进入ViewRootImpl发现:setView(...) 方法内部初始化了InputChannel
//android.view.ViewRootImpl
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,int userId) {
...
InputChannel inputChannel = null;
if ((mWindowAttributes.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
inputChannel = new InputChannel();
}
....
//WindowInputEventReceiver继承自InputEventReceiver
//对InputChannel中输入事件的监听
mInputEventReceiver = new WindowInputEventReceiver(inputChannel,
Looper.myLooper());
....
}
WindowInputEventReceiver
初始化后,构造函数里面会执行nativeInit(..)
3.6 如何触发dispatchInputEvent?
点击查看 InputEventReceiver.cpp 源码
//platform/frameworks/base/core/jni/android_view_InputEventReceiver.cpp
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
jobject inputChannelObj, jobject messageQueueObj) {
...
sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
receiverWeak, inputChannel, messageQueue);
status_t status = receiver->initialize();
...
receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object
return reinterpret_cast<jlong>(receiver.get());
}
status_t NativeInputEventReceiver::initialize() {
setFdEvents(ALOOPER_EVENT_INPUT);
return OK;
}
void NativeInputEventReceiver::setFdEvents(int events) {
if (mFdEvents != events) {
mFdEvents = events;
int fd = mInputConsumer.getChannel()->getFd();
if (events) {
//大家可以查看上面我们提供的👆👆Looper.cpp源码地址👆👆,进去看一下addFd方法
//调用Looper.addFd()完成的赋值操作
//Looper.cpp里面的 mCallback =『此处的this』
//所以:Looper.cpp里面的handleEvent = NativeInputEventReceiver::handleEvent(...)
//看文章上面的Looper::pollInner方法
mMessageQueue->getLooper()->addFd(fd, 0, events, this, nullptr);
} else {
mMessageQueue->getLooper()->removeFd(fd);
}
}
}
看一下 NativeInputEventReceiver::handleEvent(..)
//platform/frameworks/base/core/jni/android_view_InputEventReceiver.cpp
int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
....
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
//处理事件
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
return status == OK || status == NO_MEMORY ? 1 : 0;
}
...
return 1;
}
status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
.....
ScopedLocalRef<jobject> receiverObj(env, nullptr);
bool skipCallbacks = false;
for (;;) {
uint32_t seq;
InputEvent* inputEvent;
status_t status = mInputConsumer.consume(&mInputEventFactory,
consumeBatches, frameTime, &seq, &inputEvent);
....
if (!skipCallbacks) {
....
jobject inputEventObj;
switch (inputEvent->getType()) {
....
if (inputEventObj) {
//执行Java类里面的 InputEventReceiver.dispachInputEvent()
env->CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);
if (env->ExceptionCheck()) {
skipCallbacks = true;
}
env->DeleteLocalRef(inputEventObj);
}
...
}
...
}
}
执行👇👇下面这行代码,会执行到 InputEventReceiver.dispachInputEvent()
//😩不容易,终于可以跳出来了
CallVoidMethod(receiverObj.get(),
gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj)
4.enqueueInputEvent
上面触发了dispatchInputEvent之后,回调onInputEvent
//android.view.ViewRootImpl.WindowInputEventReceiver
final class WindowInputEventReceiver extends InputEventReceiver {
public void onInputEvent(InputEvent event) {
...
enqueueInputEvent(...)
...
}
}
5.doProcessInputEvents
//android.view.ViewRootImpl
void enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately) {
....
//最终还是会执行doProcessInputEvents()
if (processImmediately) {
//立即执行
doProcessInputEvents();
} else {
//延迟执行,最终还是会执行doProcessInputEvents()
scheduleProcessInputEvents();
}
}
6.doProcessInputEvents
//android.view.ViewRootImpl
void doProcessInputEvents() {
// 传递队列中所有待处理的事件
while (mPendingInputEventHead != null) {
QueuedInputEvent q = mPendingInputEventHead;
mPendingInputEventHead = q.mNext;
if (mPendingInputEventHead == null) {
mPendingInputEventTail = null;
}
q.mNext = null;
mPendingInputEventCount -= 1;
....
deliverInputEvent(q);
}
...
}
7.deliverInputEvent
//android.view.ViewRootImpl
private void deliverInputEvent(QueuedInputEvent q) {
...
InputStage stage;
if (q.shouldSendToSynthesizer()) {
stage = mSyntheticInputStage;
} else {
stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
}
....
if (stage != null) {
handleWindowFocusChanged();
//使用责任链模式,开始传递,最终会执行到ViewPostImeInputStage.onProcess
stage.deliver(q);
} else {
finishInputEvent(q);
}
...
}
8.ViewPostImeInputStage.onProcess
//android.view.ViewRootImpl.ViewPostImeInputStage
final class ViewPostImeInputStage extends InputStage {
@Override
protected int onProcess(QueuedInputEvent q) {
...
final int source = q.mEvent.getSource();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
//传递到view中
return processPointerEvent(q);
}
...
}
}
9.ViewPostImeInputStage.processPointerEvent
private int processPointerEvent(QueuedInputEvent q) {
final MotionEvent event = (MotionEvent)q.mEvent;
...
//执行view的dispatchPointerEvent,返回事件是否由此view处理
boolean handled = mView.dispatchPointerEvent(event);
maybeUpdatePointerIcon(event);
maybeUpdateTooltip(event);
mAttachInfo.mHandlingPointerEvent = false;
....
return handled ? FINISH_HANDLED : FORWARD;
}
10.View.dispatchPointerEvent
//android.view.View
public final boolean dispatchPointerEvent(MotionEvent event) {
if (event.isTouchEvent()) {//如果是触摸事件则100%是true
return dispatchTouchEvent(event);
} else {
return dispatchGenericMotionEvent(event);
}
}
11.DecorView.dispatchTouchEvent
我们进入ViewRootImpl里面再瞅一眼,上面刚刚分析的View.dispatchPointerEvent
,这个View如果是ViewGroup,那么它就是DecorView
//com.android.internal.policy.DecorView
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
//这个mWindow是PhoneWindow
final Window.Callback cb = mWindow.getCallback();
//调用:WindowCallbackWrapper.dispatchTouchEvent
return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
}
11.1 PhoneWindow怎么来的?
打开Activity的源码,能看到Activity.attatch
方法内部初始化了PhoneWindow
//android.app.Activity
final void attach(Context context, ActivityThread aThread,...) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
//初始化PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(mWindowControllerCallback);
//设置Callback
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
...
mWindowManager = mWindow.getWindowManager();
...
}
11.2 DecorView怎么和window关联到一起的?
打开PhoneWindow
,查看里面的setContentView
方法,内部调用了installDecor()
//com.android.internal.policy.PhoneWindow
private void installDecor() {
...
//这样就关联起来了
mDecor.setWindow(this);
....
}
12.WindowCallbackWrapper.dispatchTouchEvent
//curtains.internal.WindowCallbackWrapper
override fun dispatchTouchEvent(event: MotionEvent?): Boolean {
return if (event != null) {
val iterator = listeners.touchEventInterceptors.iterator()
val dispatch: (MotionEvent) -> DispatchState = object : (MotionEvent) -> DispatchState {
override fun invoke(interceptedEvent: MotionEvent): DispatchState {
return if (iterator.hasNext()) {
val nextInterceptor = iterator.next()
nextInterceptor.intercept(interceptedEvent, this)
} else {
DispatchState.from(delegate.dispatchTouchEvent(interceptedEvent))
}
}
}
//如果设置了OnTouchEventListener,那么就会执行这个iterator
if (iterator.hasNext()) {
val firstInterceptor = iterator.next()
firstInterceptor.intercept(event, dispatch)
} else {
//没有设置OnTouchEventListener的场景
//delegate = Activity
DispatchState.from(delegate.dispatchTouchEvent(event))
} is Consumed
} else {
//delegate = Activity
delegate.dispatchTouchEvent(event)
}
}
最终执行到 Activity.dispatchTouchEvent
,分析结束,终于传递到Activity了。