码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【input系统】MotionEvent的分解


    在打开多窗口的时候,比如A,B两个应用窗口,我们通过onTouchEvent查看log可以发现,在A窗口上的点击事件不会传给B窗口,当有多个点击事件时,A,B接收到的事件是不一样的,也就是说,在InputDispatcher的notifyMotion中的一个MotionEvent,在传送给app的时候,会根据窗口进行拆分。

        
        
        
        
        
        
        

    这个处理是splitMotionEvent方法,

    2317InputDispatcher::MotionEntry*
    2318InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
    2319    ALOG_ASSERT(pointerIds.value != 0);
    2320
    2321    uint32_t splitPointerIndexMap[MAX_POINTERS];
    2322    PointerProperties splitPointerProperties[MAX_POINTERS];
    2323    PointerCoords splitPointerCoords[MAX_POINTERS];
    2324
    2325    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
    2326    uint32_t splitPointerCount = 0;
    2327
    2328    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
    2329            originalPointerIndex++) {
    2330        const PointerProperties& pointerProperties =
    2331                originalMotionEntry->pointerProperties[originalPointerIndex];
    2332        uint32_t pointerId = uint32_t(pointerProperties.id);
    2333        if (pointerIds.hasBit(pointerId)) {
    2334            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
    2335            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
    2336            splitPointerCoords[splitPointerCount].copyFrom(
    2337                    originalMotionEntry->pointerCoords[originalPointerIndex]);
    2338            splitPointerCount += 1;
    2339        }
    2340    }
    2341
    2342    if (splitPointerCount != pointerIds.count()) {
    2343        // This is bad.  We are missing some of the pointers that we expected to deliver.
    2344        // Most likely this indicates that we received an ACTION_MOVE events that has
    2345        // different pointer ids than we expected based on the previous ACTION_DOWN
    2346        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
    2347        // in this way.
    2348        ALOGW("Dropping split motion event because the pointer count is %d but "
    2349                "we expected there to be %d pointers.  This probably means we received "
    2350                "a broken sequence of pointer ids from the input device.",
    2351                splitPointerCount, pointerIds.count());
    2352        return NULL;
    2353    }
    2354
    2355    int32_t action = originalMotionEntry->action;
    2356    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
    2357    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
    2358            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
    2359        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
    2360        const PointerProperties& pointerProperties =
    2361                originalMotionEntry->pointerProperties[originalPointerIndex];
    2362        uint32_t pointerId = uint32_t(pointerProperties.id);
    2363        if (pointerIds.hasBit(pointerId)) {
    2364            if (pointerIds.count() == 1) {
    2365                // The first/last pointer went down/up.
    2366                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
    2367                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
    2368            } else {
    2369                // A secondary pointer went down/up.
    2370                uint32_t splitPointerIndex = 0;
    2371                while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
    2372                    splitPointerIndex += 1;
    2373                }
    2374                action = maskedAction | (splitPointerIndex
    2375                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
    2376            }
    2377        } else {
    2378            // An unrelated pointer changed.
    2379            action = AMOTION_EVENT_ACTION_MOVE;
    2380        }
    2381    }
    2382
    2383    MotionEntry* splitMotionEntry = new MotionEntry(
    2384            originalMotionEntry->eventTime,
    2385            originalMotionEntry->deviceId,
    2386            originalMotionEntry->source,
    2387            originalMotionEntry->policyFlags,
    2388            action,
    2389            originalMotionEntry->actionButton,
    2390            originalMotionEntry->flags,
    2391            originalMotionEntry->metaState,
    2392            originalMotionEntry->buttonState,
    2393            originalMotionEntry->edgeFlags,
    2394            originalMotionEntry->xPrecision,
    2395            originalMotionEntry->yPrecision,
    2396            originalMotionEntry->downTime,
    2397            originalMotionEntry->displayId,
    2398            splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
    2399
    2400    if (originalMotionEntry->injectionState) {
    2401        splitMotionEntry->injectionState = originalMotionEntry->injectionState;
    2402        splitMotionEntry->injectionState->refCount += 1;
    2403    }
    2404
    2405    return splitMotionEntry;

    其调用流程是

    dispatchMotionLocked

    dispatchEventLocked

    prepareDispatchCycleLocked
    
    splitMotionEvent
    主要是区别出各窗口上的点,根据pointID来进行拆分,具体的分析可以参考
    ViewGroup事件分发总结-多点触摸事件拆分 - 掘金
    在应用中也有类似的拆分处理,

    可以看出,touch事件(MotionEvent)的传送多么的不容易,那么多的操作,多次加工,千辛万苦才传给了接收者。这一路,太辛苦。

  • 相关阅读:
    Python自制图片拼图小游戏
    RTC实时时钟——DS1302
    xf86-video-intel源码分析2 —— README文件
    中国芯片独角兽公司
    数字孪生技术在物流领域的应用举例
    Android中获取唯一的id
    Day42 尚硅谷JUC——Fork_Join分支合并框架
    level2行情websocket订阅
    【Steam VR 2.X】unity Skeleton Poser 骨骼姿势 编辑好手势后 运行时 抓取姿势会偏
    图问题——深度遍历,广度遍历,并查集
  • 原文地址:https://blog.csdn.net/aaajj/article/details/127097807
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号