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

Android向BroadcastReceiver传递Parcelable列表时接收数据全为null

问题根因

追加列表后所有接收到的数据变为null,是两个典型的Android PendingIntent传值坑叠加导致的:

  1. PendingIntent复用问题:你创建PendingIntent时用uid作为requestCode,且没有加FLAG_UPDATE_CURRENT标记。如果之前测试时已经用同一个uid创建过仅传uid、job的PendingIntent,系统会直接返回缓存的旧实例,不会使用你新塞入列表的Intent;同时跨进程传给AlarmManager的PendingIntent如果没有更新标记,序列化自定义Parcelable对象时会丢失类型信息。
  2. 反序列化类加载器不匹配:AlarmManager是系统服务,触发广播时会在系统进程先对Intent做反序列化,默认的类加载器找不到你项目里自定义的CharacInfo类,会直接触发反序列化失败,导致整个Bundle内的所有数据都无法正常读取,返回null。
修复方案

按以下步骤修改代码即可解决:

  • 修改PendingIntent创建逻辑,追加更新标记,适配高版本系统
    替换原有PendingIntent创建代码:
    val pendingIntentFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
    } else {
        PendingIntent.FLAG_UPDATE_CURRENT
    }
    val pendingIntent = PendingIntent.getBroadcast(context, uid, intent, pendingIntentFlag)
    
    改完首次运行建议先卸载重装应用,清除系统缓存的旧PendingIntent实例,避免旧实例干扰。
  • 修改广播接收端的读取逻辑,提前设置类加载器,适配Android 13+的API变更
    替换onReceive内读取数据的代码:
    override fun onReceive(context: Context?, intent: Intent) {
        // 给Bundle设置当前类加载器,解决自定义Parcelable反序列化失败问题
        intent.extras?.classLoader = javaClass.classLoader
    
        val uid = intent.getStringExtra(UID_KEY)
        val job = intent.getStringExtra(JOB_KEY)
        // 适配Android 13的类型安全API,避免泛型擦除问题
        val lists: ArrayList<CharacInfo>? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            intent.getParcelableArrayListExtra(LIST_KEY, CharacInfo::class.java)
        } else {
            @Suppress("DEPRECATION")
            intent.getParcelableArrayListExtra(LIST_KEY)
        }
    
        Log.d("list_key","broadcastreceiver uid : ${uid}")
        Log.d("list_key","broadcastreceiver job : ${job}")
        Log.d("list_key","broadcastreceiver list : ${lists}")
    
        val serviceIntent = Intent(context, EmptyService::class.java)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    

// context?.startForegroundService(serviceIntent)
} else {
// context?.startService(serviceIntent)
}
}

- 额外注意:Android Binder事务缓冲区有1MB的大小限制,不要通过Intent传递过大的列表。如果列表数据量多,建议先把数据存入Room数据库,广播里仅传递主键id,收到后再从数据库查询完整数据,避免传输失败。

内容的提问来源于stack exchange,提问作者luullu
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:36:20