当前位置: 首页 > news >正文

Jetpack Compose `ACTION_HOVER_EXIT` 事件异常解决方案

Jetpack Compose 1.6.6 版本中 ACTION_HOVER_EXIT 事件异常解决方案

问题现象

在 Android 应用开发中使用 Jetpack Compose 1.6.6 版本时,部分设备会出现以下崩溃日志:

java.lang.IllegalStateException: The ACTION_HOVER_EXIT event was not cleared.
    at androidx.compose.ui.platform.AndroidComposeView.sendHoverExitEvent$lambda$5(AndroidComposeView.android.kt:565)
    ...

问题背景

这个错误通常出现在以下场景:

  1. 使用鼠标或触控笔操作界面时
  2. 在平板设备或 Chrome OS 设备上
  3. 快速滑动或频繁触发悬停事件时

原因分析

该问题的根本原因是 Compose 运行时在处理 ACTION_HOVER_EXIT 事件时,事件状态未被正确清除。即使在使用最新的 1.6.6 版本时,由于以下原因仍可能出现:

  1. 设备厂商对 Android 系统的定制修改
  2. 第三方输入设备驱动发送了不规范的事件序列
  3. Compose 与传统 View 系统混合使用时事件流被污染

解决方案

方案一:事件拦截处理(推荐)

AndroidComposeView(this).apply {
    setOnGenericMotionListener { _, event ->
        when (event.action) {
            MotionEvent.ACTION_HOVER_EXIT -> {
                event.action = MotionEvent.ACTION_CANCEL
                true
            }
            else -> false
        }
    }
}

优点

  • 保留悬停功能
  • 针对性强

缺点

  • 需要为每个 ComposeView 设置

方案二:全局配置(适合纯触控应用)

// 在 Application 类中:
@SuppressLint("DiscouragedPrivateApi")
fun disableHoverEventsGlobally() {
    try {
        val field = AndroidComposeView::class.java
            .getDeclaredField("shouldDispatchHoverEvents")
        field.isAccessible = true
        field.setBoolean(null, false)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

优点

  • 一劳永逸
  • 适合不需要悬停效果的应用

缺点

  • 使用反射,可能有兼容性问题
  • 会完全禁用悬停效果

方案三:升级到预览版本

implementation 'androidx.compose.ui:ui:1.7.0-alpha03'

优点

  • 官方修复方案
  • 从根本上解决问题

缺点

  • 使用 alpha 版本可能存在稳定性风险

验证方法

  1. 最小化测试:
class TestActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hover Test") // 仅显示简单文本测试
        }
    }
}
  1. 监控日志:
adb logcat | grep -E "HOVER|Compose"

最佳实践建议

  1. 对于生产环境应用
    • 优先使用方案一(事件拦截)
    • 在关键界面添加异常捕获
  2. 对于新开发项目
    • 考虑使用 Compose 1.7.0-alpha 版本
    • 充分测试各种输入设备
  3. 兼容性处理
fun isHoverBrokenDevice(): Boolean {
    return Build.MANUFACTURER.equals("特定问题厂商", ignoreCase = true) 
            || Build.MODEL.contains("Chromebook")
}

延伸阅读

  1. 官方 Issue 追踪

  2. Compose 输入事件处理文档

  3. Compose 1.7.0 变更日志

  4. Stack Overflow: Compose app crashes when scrolling with a mouse

    Google Issue Tracker: The ACTION_HOVER_EXIT event was not cleared.

总结

Jetpack Compose 1.6.6 中的 Hover 事件问题可以通过多种方式解决。建议根据项目实际情况选择合适的方案,并及时关注官方更新以获取永久性修复。

http://www.dtcms.com/a/111663.html

相关文章:

  • 纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
  • MySQL-SQL-DDL语句、表结构创建语句语法、表约束、表数据类型
  • Dive into Deep Learning - 2.4. Calculus (微积分)
  • Netty——连接超时 与 断开重连
  • Linux命令-grep
  • 人工智能爬虫导致维基共享资源带宽需求激增 50%
  • 计算机系统---GPU
  • 【小沐杂货铺】基于Three.JS绘制太阳系Solar System(GIS 、WebGL、vue、react)
  • centosububntu设置开机自启动
  • Upload-labs靶场通关
  • 06-31-自考数据结构(20331)- 查找技术-哈希表例题分析
  • 在CPU服务器上部署Ollama和Dify的过程记录
  • 批量图片文本识别重命名,批量ocr识别图片重命名,基于WPF和腾讯OCR云部署实,现批量对图片局部提取文字后重命名的操作详细步骤
  • PyTorch模型 train() 和 eval() 模式详解
  • Python 入门指南:从基础语法到应用场景
  • React-02初学hello_react(JSX,创建React根节点,引入对应React库,render渲染DOM)
  • MIT6.828 Lab3-3 Detect which pages have been accessed (hard)
  • MCP有哪些比较好的资源?
  • 数据一键导出为 Excel 文件
  • 每日一个小病毒(C++)EnumChildWindows+shellcode
  • 添加购物车功能
  • LeetCode热题100记录-【链表】
  • Linux内核物理内存组织结构
  • 【GPT入门】第33课 从应用场景出发,区分 TavilyAnswer 和 TavilySearchResults,代码实战
  • [每周一更]-(第138期):MySQL 子查询详解:原理、应用及优化方案
  • 爬虫工程师的社会现状
  • ISIS多区域配置
  • 基于CATIA参数化块体建模的自动化插件开发实践——NX建模之块命令的参考与移植
  • 4.3-2 jenkins
  • Cortex-M​ 中断的压栈与出栈操作