Search code examples
androidkotlinandroid-recyclerviewsharedpreferences

Issue with SharedPreferences saving data to object list


I'm struggling to figure out what's wrong with my code. I'm using a combination of RecyclerView and SharedPreferences to create a simple shopping list. The idea is to first input a name of the shopping list and when the user clicks on the name of that added list (selects it), a new activity will open with that object passed (retrieved via serializableExtra) and you'll be able to add shopping items into the list of that specific object.

In my main activity where I save a list of the shopping list object, SharedPreferences works perfectly (together with gson), however, when I try to replicate that thing for a list of shopping items in that second activity, my application crashes. It seems as if it goes into a loop as my build log goes out of memory.

I have already debugged the code and the issue happens at the function saveData(), runs fine otherwise. Any help would be appreciated.

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()
        }

    }
}

Solution

  • I've managed to resolve it eventually. If anybody comes across this issue, make sure you go through each class to find if you have set up the properties properly. The answer was similar to this one: Servlet Gson().toJson infinite loop