美文网首页Android Android
Android事件从底层传递到Activity过程

Android事件从底层传递到Activity过程

作者: 天上飘的是浮云 | 来源:发表于2022-04-03 11:04 被阅读0次

    Android中事件上层的分发、拦截、处理还是比较好理解的,那么事件是如何从点击屏幕传到Activity,再有Activity分发给它自己的View的呢?

    这里可能要分为两层:1、手机点击屏幕 事件传回--> Activity;2、Activity如何分发给子ViewGroup、View?

    一、关于屏幕点击后的流程看图:

    image.png

    二、屏幕点击后,事件如何监听?如何分发?

    1.1 在深入看底层代码前我们先要了解几个知识。
    • 1、屏幕事件有驱动保存在/dev/input/event0文件中
    • 2、底层对/dev/input/event0主要使用Epoll+iNotify机制监听


      image.png
    1.2 下图是SystemServer进程开始IMS后,Native监听到事件后,准备由SystemServer进程发送到App进程的Activity阶段。
    • 1、SystemServer实例化了InputManagerService实例,而上层的IMS实际依赖Native层的IMS来起作用。
    • 2、Native层IMS会实例化一个EventHub和InputManager实例,EventHub主要封装了Epoll和iNotify机制,用来实现对/dev/input文件进行监控
    • 3、InputManager构造方法中会实例InputReader和InputDispatcher,它们分别对事件读取和分发
    • 4、并且新建两个线程InputReaderThread和InputDispatcherThread来处理有关读取事件和分发事件的事项
    • 5、InputReaderThread线程开启后,通过epoll_wait阻塞,只到有事件发生(epoll_ctl)就会继续执行,封装事件,并将事件存储在mInboundQueue队列中。
    • 6、InputDispatcherThread线程开启后,会去mInboundQueue队列中取事件,有就开始分发
    • 7、因为此时IMS处于SystemServer进程,事件要发送给Activity(App进程)。这是跨进程通信。但是他这里不是使用Binder来通信,而是使用的SocketPair。
    • 8、下图到了InputTransport.cpp publishMotionEvent()方法中 mChannel -> sendMessage(&msg)就是开始向上层Activity传递事件了。
    事件分发底层.png

    三、Native底层获取信息后,如何跨进程通信传给上层App的Activity?

    3.1 SystemServer进程和App进程建立链接用于事件传递
    • 1、前面知道ActivityThread调到了handleResumeActivity方法,通过mWM.addView。最终会到ViewRootImpl的setView方法。
    • 2、setView方法里,通过Session通信来到了WMS.addWindow
    • 3、WMS.addWindow会调用到WindowState.openInputChannel方法
    • 4、WindowState.openInputChannel会通过InputChannel.openInputChannelPair去底层创建两个SocketPair实例,一个用于写,一个用于读取。
    • 5、创建好的两个SocketPair,会同时作用于一块区域,一个给Native层用于写事件,一个会调给上层用于读事件。
    • 6、到这里就是建立好了SystemServer进程和App进程之间的链接,它们可以通信了。
    3.2 链接建立好后,Native层事件会调给Activity
    • 1、回到ViewRootImp.setView方法,在建立链接后,会实例化一个WindowInputEventReceiver对象,它将用于接受底层发送过来的事件。
    • 2、WindowInputEventReceiver继承至InputEventReceiver,InputEventReceiver构造方法中会调用nativeInit,会对应构建一个NativeInputEventReceiver实例。并将InputChannel和MessageQueue传入。
    • 3、NativeInputEventReceiver就类似于Handler机制,在consumeEvents中收到InputDispatcher发出的事件。将会回调InputEventReceiver.java的dispatchToucheEvent方法
    • 4、然后因为WindowInputEventReceiver是InputEventReceiver子类,会调用到WindowInputEventReceiver的onInputEvent方法。
    • 5、一路调用最终回到ViewPostimeInputStage的processPointerEvent方法
    • 6、而processPointerEvent方法中会调用View的dispatchPointerEvent方法
    • 7、dispatchPointerEvent方法中会调用dispatchTouchEvent方法,而在ViewRootImpl中mView实际是DecorView。
    • 8、那么就进入到DecorView的dispatchTouchEvent方法,在该方法中会调用mWindow.getCallback().dispatchTouchEvent方法。
    • 9、而在Activity的attach方法中又mWindow.setCallback(this),所以mWindow.getCallback()其实就是Activity对象,Activity也实现了Window.Callback接口。
    • 10、到这事件就到了Activity的dispatchTouchEvent来了,接下来就是应用层,Activity分发给它的子ViewGroup和子View了。
    事件分发SystemServer进程与APP通信建立,以及传递给Activity.png

    相关文章

      网友评论

        本文标题:Android事件从底层传递到Activity过程

        本文链接:https://www.haomeiwen.com/subject/pgwykrtx.html