Android 事件处理

输入事件传递流程的组成部分
输入系统是外界与Android设备交互的基础,仅凭输入系统是无法完成输入事件传递的,因此需要输入系统和Android系统的其他成员来共同完成事件传递。输入事件传递流程可以大致的分为三个部分,分别是输入系统部分、WMS处理部分和View处理部分。

 

IMS的诞生
MS所做的工作就是监听/dev/input下的所有的设备节点,当设备节点有数据时会将数据进行加工处理并找到合适的Window,将输入事件派发给它。

与AMS、WMS、PMS一样,IMS的在SyetemServer进程中被创建的,并添加到ServiceManager中进行统一的管理
frameworks/base/services/java/com/android/server/SystemServer.java

inputManager = new InputManagerService(context);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);


需要注意的是,WMS也是这个时候创建,并把IMS做为参数传入,WMS和IMS关联起来


getAction()     获取事件类型。
getX()  获得触摸点在当前 View 的 X 轴坐标。
getY()     获得触摸点在当前 View 的 Y 轴坐标。
getRawX()     获得触摸点在整个屏幕的 X 轴坐标。
getRawY()     获得触摸点在整个屏幕的 Y 轴坐标。

Activity创建过程中会创建PhoneWindow ViewRootImpl 和DecorView,

将DecorView最终添加到Window上,在这个过程中,
ViewRootImpl、DecorView和WMS会彼此向关联,
同时会创建InputChannel、InputQueue和WindowInputEventReceiver来接收点击事件的消息

DecorView相当activity的一个父容器,继承的是FrameLayout,FrameLayout继承的是ViewGroup

事件最终上层最终在DecorViewd 的dispatchTouchEvent分发

 


    public boolean dispatchTouchEvent(MotionEvent ev) {
        final Window.Callback cb = mWindow.getCallback();
        return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
                ? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
    }
Activity实现了一个特殊的接口:Window.Callback

在Activity的attach方法中
mWindow 通过setCallback方法来持有Activity
通过callback将事件传递到activity
    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) {
        attachBaseContext(context);

        mFragments.attachHost(null );

        mWindow = new PhoneWindow(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);

 

        
        
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }
    首先调用PhoneWindow的superDispatchTouchEvent方法,如果未处理才继续调用onTouchEvent方法
    
    PhoneWindow的superDispatchTouchEvent方法,直接调用DecorView的superDispatchTouchEvent
    public  boolean superDispatchTouchEvent(MotionEvent event){
        return mDecor.superDispatchTouchEvent(event);
    };

    所以事件最终传递给了ViewGroup
    public boolean superDispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }
    
    
ViewGroup中 dispatchTouchEvent
1.检查是否拦截事件
onInterceptTouchEvent默认

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值