SharedPreferences 将数据保存到对象列表时出现问题

Issue with SharedPreferences saving data to object list

我正在努力弄清楚我的代码有什么问题。我结合使用 RecyclerView 和 SharedPreferences 来创建一个简单的购物清单。这个想法是首先输入购物清单的名称,当用户单击该添加清单的名称(选择它)时,一个新的 activity 将打开并传递该对象(通过 serializableExtra 检索)并且您'您将能够将购物项目添加到该特定对象的列表中。

在我保存购物清单对象列表的主要 activity 中,SharedPreferences 完美地工作(与 gson 一起),但是,当我尝试为其中的购物清单复制那个东西时第二 activity,我的应用程序崩溃了。当我的构建日志内存不足时,它似乎进入了一个循环。

我已经调试了代码,问题发生在函数 saveData() 上,否则运行正常。任何帮助将不胜感激。

fun saveData (){
        var sharedPreferences: SharedPreferences = getSharedPreferences("Liste_u_objektu", MODE_PRIVATE)
        var editor: SharedPreferences.Editor = sharedPreferences.edit()
        var gson = Gson()
        var json: String = gson.toJson(listSource)
        editor.putString("Spremi_Objekt", json)
        editor.apply()
    }

SingleListActivity.kt

package com.example.simpleshoppinglist

import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import com.example.simpleshoppinglist.adapter.ShoppingItemAdapter
import com.example.simpleshoppinglist.model.ShoppingItem
import com.example.simpleshoppinglist.model.SingleLista
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

val activityIntentId: Int = 1


class SingleListActivity : AppCompatActivity() {

    //Empty init
    var singleList = SingleLista ("Placeholder")
    var listSource = singleList.listOfShoppingItems
    var shoppingItemAdapter = ShoppingItemAdapter(this, listSource)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_single_list)

        val getObjectFromRecyclerOnClick = intent.getSerializableExtra("Extra_object") as SingleLista
        singleList = getObjectFromRecyclerOnClick
        listSource = singleList.listOfShoppingItems
        loadData()

        shoppingItemAdapter = ShoppingItemAdapter(this, listSource)
        var recyclerViewSingle = findViewById<RecyclerView>(R.id.recycler_view_single)
        val btnAddShoppingItem: Button = findViewById(R.id.btnDodajNamirnicu)
        recyclerViewSingle.adapter = shoppingItemAdapter

        btnAddShoppingItem.setOnClickListener {
            val intent = Intent(this, AddShoppingItemActivity::class.java)
            intent.putExtra("SinglLista", singleList)
            this.startActivityForResult(intent, activityIntentId)
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == activityIntentId) {
            if (resultCode == RESULT_OK) {
                //var testniLabel: TextView = findViewById(R.id.TESTNILABEL)
                //testniLabel.text = "TEST LABEL"
                var shoppingItemName = data?.getSerializableExtra("NazivNamirnice") as String
                var shoppingItemQuantity = data?.getSerializableExtra("KolicinaNamirnice") as String
                addShoppingItem(
                    shoppingItemName,
                    shoppingItemQuantity,
                    shoppingItemAdapter,
                )

                saveData()
            }
        }

    }

    fun saveData (){
        var sharedPreferences: SharedPreferences = getSharedPreferences("Liste_u_objektu", MODE_PRIVATE)
        var editor: SharedPreferences.Editor = sharedPreferences.edit()
        var gson = Gson()
        var json: String = gson.toJson(listSource)
        editor.putString("Spremi_Objekt", json)
        editor.apply()
    }

    fun loadData(){
        var sharedPreferences: SharedPreferences = getSharedPreferences("Liste_u_objektu", MODE_PRIVATE)
        var gson = Gson()
        if (sharedPreferences.getString("Spremi_Objekt", null) != null){
            var json: String = sharedPreferences.getString("Spremi_Objekt", null)!!
            val turnsType = object : TypeToken<MutableList<ShoppingItem>>() {}.type
            listSource = gson.fromJson(json,turnsType)
        }

        else{
            listSource.clear()
        }
    }

    fun addShoppingItem(
        shoppingItemName: String,
        shoppingItemQuantity: String,
        adapter: ShoppingItemAdapter,
    ) {
        listSource.add(ShoppingItem(
            shoppingItemName,
            shoppingItemQuantity.toInt(),
            singleList
        ))
        adapter.notifyDataSetChanged()
    }

}

AddShoppingItemActivity.kt

package com.example.simpleshoppinglist

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText

class AddShoppingItemActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dodaj_namirnicu)
        val shoppingItemName: EditText = findViewById(R.id.nazivNamirniceEditText)
        val shoppingItemQuantity: EditText = findViewById(R.id.kolicinaNamirniceEditText)
        val btnAddShoppingItem: Button = findViewById(R.id.btnSpremiNamirnicu)


        btnAddShoppingItem.setOnClickListener {
            val intent = Intent(this, SingleListActivity::class.java)
            intent.putExtra("NazivNamirnice",shoppingItemName.text.toString())
            intent.putExtra("KolicinaNamirnice",shoppingItemQuantity.text.toString())
            setResult(Activity.RESULT_OK,intent)
            finish()
        }

    }
}

在我看来,您的字符串可能太大了。虽然您的共享首选项的 xml 文件的实际大小没有限制,但有些人 运行 遇到了问题:Shared Preferences - max length of a single value

你真的应该使用 sqlite 或 Room 来存储你的列表。

我最终设法解决了它。 如果有人遇到此问题,请确保检查每个 class 以查看是否已正确设置属性。 答案与此类似:Servlet Gson().toJson infinite loop