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

从不同Activity启动ThreadActivity时SharedPreferences失效问题

问题:SharedPreferences数据读取异常,仅特定启动方式失效

我有一个ThreadActivity,包含saveContact和loadContact两个函数,均通过SharedPreferences配合Gson存储/读取SimpleContact对象组成的ArrayList。保存后立即加载正常,但关闭Activity重新打开时,从特定页面启动无法读取SharedPreferences中的数据——两个Activity都能打开ThreadActivity,其中一个启动完全正常,另一个启动时读取到的数据为空。

保存函数

private fun saveContact() {
        val gson = Gson()
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
        try {
            val editor = sharedPreferences.edit()
            val json = gson.toJson(participants)
            editor.putString(threadId.toString()+"_Contact", json)
            editor.apply()
        } catch(e: Exception) {
            e.printStackTrace()
        }
}

加载函数

private fun loadContact() {
        val gson = Gson()
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
        val type = object : TypeToken<ArrayList<SimpleContact?>>() {}.type
        try {
            val json = sharedPreferences.getString(threadId.toString()+"_Contact", "")
            participants = gson.fromJson(json, type)
        } catch(e: Exception) {
            e.printStackTrace()
        }
}

可正常启动ThreadActivity的代码

private fun launchThreadActivity(phoneNumber: String, name: String) {
        hideKeyboard()
        val text = intent.getStringExtra(Intent.EXTRA_TEXT) ?: ""
        val numbers = phoneNumber.split(";")
        val number = if (numbers.size == 1) phoneNumber else Gson().toJson(numbers)
        Intent(this, ThreadActivity::class.java).apply {
            putExtra(THREAD_ID, getThreadId(numbers))
            putExtra(THREAD_TITLE, name)
            putExtra(THREAD_TEXT, text)
            putExtra(THREAD_NUMBER, number)

            if (intent.action == Intent.ACTION_SEND && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true) {
                val uri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
                putExtra(THREAD_ATTACHMENT_URI, uri?.toString())
            } else if (intent.action == Intent.ACTION_SEND_MULTIPLE && intent.extras?.containsKey(Intent.EXTRA_STREAM) == true) {
                val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
                putExtra(THREAD_ATTACHMENT_URIS, uris)
            }

            startActivity(this)
        }
}

无法正常启动(读取数据为空)的代码

Intent(this, ThreadActivity::class.java).apply {
                        putExtra(THREAD_ID, (it as Conversation).threadId)
                        putExtra(THREAD_TITLE, it.title)
                        putExtra("fromMain", true)
                        startActivity(this)
}

问题分析与解决方案

核心问题大概率是两种启动方式传入的THREAD_ID不一致,导致存储和读取时使用的SharedPreferences键名不匹配:

  • 正常启动时通过getThreadId(numbers)生成ID,异常启动时直接传入Conversation.threadId,两者的生成逻辑或数据类型可能不同(比如一个是String,一个是Long,toString后格式有差异)。
  • 加载时如果threadId为空或与存储时的键名不匹配,就会读取到默认空字符串,Gson解析后得到null或空列表。

修复步骤:

  1. 统一THREAD_ID的生成与传递逻辑
    检查getThreadId(numbers)的实现,确保异常启动时传入的Conversation.threadId与该函数生成的ID完全一致(包括数据类型、字符串格式)。比如如果getThreadId返回的是字符串,那么Conversation.threadId也要转为相同格式的字符串再传递。

  2. 添加threadId非空校验
    在saveContact和loadContact中先判断threadId是否有效,避免使用空值生成无效键名:

    private fun saveContact() {
        val threadIdStr = threadId?.toString() ?: return // 空则直接返回
        val gson = Gson()
        val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(applicationContext)
        try {
            val editor = sharedPreferences.edit()
            val json = gson.toJson(participants)
            editor.putString("$threadIdStr_Contact", json)
            editor.apply()
        } catch(e: Exception) {
            e.printStackTrace()
        }
    }
    
  3. 调试阶段验证写入同步
    apply()是异步提交,调试时可临时换成commit()确认数据是否同步写入(线上仍推荐用apply()):

    editor.commit() // 替换editor.apply()
    
  4. 检查SimpleContact序列化有效性
    确保SimpleContact类是可被Gson正常序列化的:

    • 避免内部非静态匿名类
    • 字段需为public,或添加@SerializedName注解配合getter/setter
    • 若有继承关系,父类也需满足序列化要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:40:39