android源码分析——事件输入流程MotionEvent事件处理流程

本文深入探讨了Android应用中MotionEvent触摸事件的处理流程,从Window、WindowManager到Activity的attach函数,再到PhoneWindow、DecorView的设置,以及ViewRootImpl在事件传递中的关键作用。通过分析InputChannel和InputEventReceiver,揭示了事件如何通过JNI和消息队列从底层传递到上层,并在View层次中进行分发和处理。最后,文章提到了Activity、DecorView的触摸事件回调,以及事件在父视图和子视图间的传递机制。
摘要由CSDN通过智能技术生成

Input事件输入系统之应用MotionEvent触摸事件处理流程
输入事件一般分为KeyEvent按键事件,和MotionEvent触摸事件,也就是我们平时说的touch事件,事件的传递流程相当复杂庞大,
我们先暂时绕开那个庞大的系统来谈谈上层应用如何接收到MotionEvent事件然后处理的,在讲这个之
前我们先提几个相关类:
Window,WindowManager,PhoneWindow,IWindowManager,WindowManagerService,咋一看,这些东西都是与Window有关
的,平时我们用的也蛮多的也就是WindowManager对象,这些东西是怎么如何我们的MotionEvent事件相关联起来的,这就是我们接
下来分析的重点。由于我们就是简单的分析下应用层的输入输出事件的分析,所以Input系统的硬件抽象层我们只是简答的提一
下。等下次的时候在重点分析该流程的通信协议。
由于有的客官已经知道了Activity的启动流程,那么我们就抽出与我们事件传递相关的一点点东西,view的加载流程,结合我们之前
提到的几个window的概念来分析与MotionEvent事件的联系
首先我们来看下Activity的attach函数

final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token,  int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window) {

attachBaseContext(context);

mFragments.attachHost( null  /*parent*/ );

mWindow =  new PhoneWindow( this, window);
w mWindow.setWindowControllerCallback( this);
//很重要的一个接口回调设置,因为事件传入Activity需要这个接口回调的传递,这点后面我们会继续分析。
w mWindow.setCallback( this);

w mWindow.setOnWindowDismissedCallback( this);
w mWindow.getLayoutInflater().setPrivateFactory( this);
。。。。。。。。。。中间省略
w mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context. WINDOW_SERVICE ),
mToken,  mComponent.flattenToString(),
(info. flags & ActivityInfo. FLAG_HARDWARE_ACCELERATED ) != 0);
if ( mParent != l null) {
w mWindow.setContainer( mParent.getWindow());
}
mWindowManager =  mWindow.getWindowManager();

从上面的函数中,我们可以看到我们上面提过的几个window概念了,
我们先看下我们的mWindow到底是什么东西
private Window mWindow;
由上面的方法里面可知,原来我们是new了一个PhoneWindow对象,而我们的PhoneWindow就是Window抽象类的继承类
那么我们接下来分析activity中的 onCreate 方法 中的setContentView方法
从字面意思上我们可以理解为填充内容的view,那么他是怎么填充进去的,我们继续分析

public void setContentView(@LayoutRes  int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}

原来他是通过PhoneWindow来调用setContetnView方法的,那么我们继续分析该方法
这里写图片描述

相信很多同学都知道该方法,其实就是实例化一个 DecoreView ,然后把我们的 contentView 填充到 DecoreView 中
那么我们是这么把这个 decoreviewt 填充到我们的 Window 中的呢,其实接下来我们就要说说我们的 WindowManager 的作用。
那么我们就继续看 view 填充过程,在我们的 Activity 调用 OnResume 之前我们需要调用主线程 ActivityThread 的 handleOnresume 来
把我们的 View 填充到 window 中,废话不多说我们来分析下:
ActivityThread.java

final void handleResumeActivity(IBinder token,
boolean clearHide,  boolean isForward,  boolean reallyResume,  int seq, String reason) {
if (r. window ==  null && !a.mFinished && willBeVisible) {
final Activity a = r.activity;
r. window = r. activity.getWindow();
View decor = r.w window.getDecorView();
decor.setVisibility(View. INVISIBLE );
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r. window.getAttributes();
a.mDecor = decor;
l. type = WindowManager.LayoutParams. TYPE_BASE_APPLICATION ;
l. softInputMode |= forwardBit;
if (r. mPreserveWindow) {
a.mWindowAdded =  true;
r. mPreserveWindow =  false;
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值