You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 16 Beta2下HostApduService实例异常问题求助

Android 16 Beta 2中HostApduService实例复用问题分析

你的实现没有错误,这是Android 16 Beta版本中未在官方文档明确提及的内部行为变更——系统现在会复用HostApduService的单个实例处理多次NFC会话,而非旧版本那样每次会话创建新实例。

日志细节说明

从你提供的日志能看到:Android 16 Beta 2中,每次读卡器靠近时,processCommandApdu和onDeactivated都正常被调用,只是服务实例始终保持同一个。你提到的“后续尝试无法正常工作”,大概率是项目代码依赖了“每次会话创建新服务实例”的隐含特性(比如在init块中初始化会话专属状态,但未在onDeactivated中重置这些状态)。

修复方案

HostApduService的设计本身就支持复用实例处理多个会话,因此需要调整代码,不再依赖服务实例的创建/销毁来管理会话状态:

  • 将会话专属的状态变量,从类成员(依赖实例生命周期)改为processCommandApdu方法内的局部变量,或者在每次会话开始时显式初始化。
  • 在onDeactivated方法中重置所有会话相关的状态,确保下一次会话开始时状态是干净的。

调整后的示例代码:

class MyHostApduService: HostApduService() {
    // 会话专属状态,需在每次会话前后重置
    private var sessionState: String? = null

    init {
        println("MyHostApduService ---> $this")
    }

    override fun processCommandApdu(bytes: ByteArray?, bundle: Bundle?): ByteArray {
        // 每次会话开始时初始化状态
        sessionState = "NewSession_${System.currentTimeMillis()}"
        println("MyHostApduService processCommandApdu ${bytes?.toHexString()}, $bundle, session: $sessionState")
        return byteArrayOf(0xA5.toByte())
    }

    override fun onDeactivated(reason: Int) {
        println("MyHostApduService onDeactivated $reason")
        // 会话结束后重置状态
        sessionState = null
    }
}

额外说明

Android系统对Service的实例管理策略本就存在版本差异,旧版本每次创建新实例的行为是系统实现细节,而非HostApduService的契约要求。Android 16的这次变更属于性能优化,复用实例减少了对象创建和销毁的开销,符合Service组件的设计预期。

内容的提问来源于stack exchange,提问作者rmh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 02:52:26