0

I am having some trouble understanding sharedPreferences and how to save and retrieve a list of objects between different activities. I followed the steps from multiple other questions, I will list them below,but I keep running into a mismatch in conversion no matter how I change it. I do get access to the list saved in sharedPreference but I am unable to convert it back to the object list. My main activity code that does an http request and saves the response object list to sharedpreferences and finally starts the next intent is:

    private fun getItems(authResponse: AuthResponseModel) {
            val url = "/Api/items";
    
            val formBody = FormBody.Builder()
                    .add("token", authResponse.cloverToken.toString())
                    .build()
    
            // creating request
            var request = Request.Builder()
                    .addHeader("Authorization", "Bearer " + authResponse.token.toString())
                    .url(url)
                    .post(formBody)
                    .build()
    
            var client = OkHttpClient();
            runOnUiThread{
    
                client.newCall(request).enqueue(object : Callback {
                    override fun onResponse(call: Call, response: Response) {
    
                        var response = response.body?.string();
    
                        //save auth token
                        val gson = Gson()
    
                        System.out.println("clover 2: " + gson.toJson(response));
                        val preferences = getSharedPreferences("items", MODE_PRIVATE)
                        preferences.edit().putString("items", gson.toJson(response)).commit()
    
                        val intent = Intent(this@MainActivity, OrderActivity::class.java)
                        intent.putExtra("SHOW_WELCOME", true)
                        startActivity(intent)
                        finish()
                    }
    
                })
            }
        }

How I retrieve the data in the other activity is below:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_order)
        initialize()
        var arrayItems: List<ItemModel>;


        initPermissions()
        val itemList = getSharedPreferences("items", MODE_PRIVATE)
        val gson = Gson()
        if (itemList != null) {
            val type = object : TypeToken<List<ItemModel>>() {}.type
            arrayItems = gson.fromJson(gson.toJson(itemList), type)
            println("here items " +arrayItems.toString())

        }

        //this.items = (itemList);

    }

I need the items to be a list of ItemModel objects that are returned from sharedpreferences. My main errors I am getting are with the conversions. Let me know if any further information is needed and I will update my question.

The ItemModel code is:

package com.robotemi.sdk.dinengo.models;

import java.util.ArrayList;

public class ItemModel {
        private String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;
        private String alternateName;
        private String code;
        private String priceType;
        private String unitName;
        private boolean sku;
        private boolean isRevenue;
        private boolean available;
        private boolean autoManage;
        private boolean defaultTaxRates;
        private double price;
        private double cost;
        private double stockCount;
        private int modifiedTime;

        public ItemModel() {}
        public ItemModel(ItemModel itemModel) {
            this.id = itemModel.id;
            this.name = itemModel.name;
            this.alternateName = itemModel.alternateName;
            this.code = itemModel.code;
            this.priceType = itemModel.priceType;
            this.unitName = itemModel.unitName;
            this.sku = itemModel.sku;
            this.isRevenue = itemModel.isRevenue;
            this.available = itemModel.available;

            this.autoManage = itemModel.autoManage;
            this.defaultTaxRates = itemModel.defaultTaxRates;
            this.price = itemModel.price;
            this.cost = itemModel.cost;
            this.stockCount = itemModel.stockCount;
            this.modifiedTime = itemModel.modifiedTime;
        }

        public ArrayList<ItemModel> ItemModel(ItemModel[] itemModel) {
            ArrayList items = new ArrayList<ItemModel>();
            for(int i = 0; i <itemModel.length ; i++ ){
                ItemModel item = new ItemModel();
                item.id = itemModel[i].id;
                item.name = itemModel[i].name;
                item.alternateName = itemModel[i].alternateName;
                item.code = itemModel[i].code;
                item.priceType = itemModel[i].priceType;
                item.unitName = itemModel[i].unitName;
                item.sku = itemModel[i].sku;
                item.isRevenue = itemModel[i].isRevenue;
                item.available = itemModel[i].available;
                item.autoManage = itemModel[i].autoManage;
                item.defaultTaxRates = itemModel[i].defaultTaxRates;
                item.price = itemModel[i].price;
                item.cost = itemModel[i].cost;
                item.stockCount = itemModel[i].stockCount;
                item.modifiedTime = itemModel[i].modifiedTime;
                items.add(item);
            }

            return items;

        }

}

It is giving me the error at this code segment:

    arrayItems = gson.fromJson(gson.toJson(itemList), type)

And the error is:

FATAL EXCEPTION: main
    Process: com.robotemi.sdk.sample, PID: 16098
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.robotemi.sdk.sample/com.robotemi.sdk.dinengo.OrderActivity}: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:772)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:662)
     Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
        at com.google.gson.Gson.fromJson(Gson.java:944)
        at com.google.gson.Gson.fromJson(Gson.java:897)
        at com.google.gson.Gson.fromJson(Gson.java:846)
        at com.robotemi.sdk.dinengo.OrderActivity.onCreate(OrderActivity.kt:162)
        at android.app.Activity.performCreate(Activity.java:6266)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)

The list of other questions I looked into but no luck:

How to save List<Object> to SharedPreferences?

How to save List<Object> to SharedPreferences?

When trying the suggested answer below, I got the following error: enter image description here

z123
  • 193
  • 1
  • 15
  • `preferences.edit().putString("response", response)`. Just save that string. That response text. You know how to handle the response if you retrieve it later – blackapps Sep 28 '22 at 04:54
  • I think your API response returning JSONObject, and you are trying to convert it into list directly. check this answer, it may helps you to understand your issue: https://stackoverflow.com/questions/73537645/retrofit-e-api-expected-begin-array-but-was-begin-object-at-line-1-column-2-pat/73537695#73537695 – Bhoomika Patel Sep 28 '22 at 04:56
  • You have a response parameter and a local variable with the same name. Confusing and strange. – blackapps Sep 28 '22 at 04:59
  • can you guys show how making a change in saving the response as a string would change the function to convert it to a JSON Object. There has to be a java library or a way that makes this simpler. – z123 Sep 28 '22 at 05:56
  • I came across that while researching. I use to save the response as a string, that is not the issue. lets assume the response saved as the string in sharedPreferences, how can I convert that string to a list of objects of type ItemModel? – z123 Sep 28 '22 at 05:58

1 Answers1

0

Try it this way

 fun toSurveyPoints(surveyPoints: List<SurveyPoint?>?, context: Context?): String? {
        if (surveyPoints == null) {
            return null
        }
        val convertedValue: String = Gson().toJson(surveyPoints)
        val preferences = PreferenceManager.getDefaultSharedPreferences(context)
        val editor = preferences.edit()
        editor.putString("", convertedValue)
        editor.apply()
        return convertedValue
    }


    fun fromSurveyPoints(context: Context?): List<SurveyPoint?>? {
        val preferences = PreferenceManager.getDefaultSharedPreferences(context)
        val surveyPoints = preferences.getString("", "") ?: return null
        return Gson().fromJson(surveyPoints, object : TypeToken<List<SurveyPoint?>?>() {}.getType())
    }
pintu236
  • 148
  • 2
  • 11