当前位置: 首页 > 知识库问答 >
问题:

在SharedReferences中存储序列化的ArrayList-检索时ArrayList为空

傅恺
2023-03-14

下面的代码当然不是做我需要做的事情的最佳方式,但不幸的是,我没有太多时间回去改变数据结构/存储选项等。然而,它将被清理干净。不管怎样,代码的质量不是我的问题,我跑题了。

用户第一次注册他们的帐户时,他们会得到一个带有多项选择(复选框)的ListView。所选项目存储在SparseBooleanArray中,然后转换为ArrayList of Strings。

ListView项的名称来自名为getStoreNames()的SQLite数据库方法,该方法返回存储名称字符串的ArrayList。

然后,我需要获取与每个商店名称关联的商店对象。这是在continue_按钮框内的for循环中完成的。(Store Store=db.returnStoreByName(storeName)。。。然后将这些存储添加到存储的ArrayList中。

然后我试图存储这个ArrayList的商店在共享首选项。因为SPs不支持ArrayList,所以数据被序列化。在下一次活动中,当我尝试访问Store对象时,我反序列化共享首选项对象。但是,当我检查反序列化的ArrayList的大小时,它是0。在序列化它并将其放入共享首选项之前,我检查了数组列表大小,它给出了正确的大小。

这让我相信,在序列化/反序列化或存储/从共享首选项检索之间的某个地方出了问题,数组列表被清空了。

这是第一个将数据保存到共享pref的活动。

package com.mad.losesano2;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import org.json.JSONArray;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class StoreListRegisterActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener{

    ListView list_view;
    List<String> stores;
    DB db;
    ArrayList<String> users_stores;
    SharedPreferences sp;
    Button continue_button;
    ArrayList<Store> stores_objects = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_store_list_register);

        list_view = (ListView) findViewById(R.id.list_view);
        list_view.setOnItemClickListener(this);
        list_view.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        list_view.setItemsCanFocus(false);

        continue_button = (Button) findViewById(R.id.continue_button);
        continue_button.setOnClickListener(this);

        db = new DB(getApplicationContext());

        stores = db.getStoreNames();

        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, stores);

        list_view.setAdapter(arrayAdapter);

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        SparseBooleanArray a = list_view.getCheckedItemPositions();

        users_stores = new ArrayList<>();


        for (int i = 0; i < stores.size(); i++){
            if(a.valueAt(i)){
                String store_name = list_view.getAdapter().getItem(a.keyAt(i)).toString();
                users_stores.add(store_name);
            }
        }

    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.continue_button:

                sp = getSharedPreferences("storeList", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                for (String storeName : users_stores) {
                    Store store = db.returnStoreByName(storeName);
                    stores_objects.add(store); 
                    Log.d("LoSeSANO", "Store name: " + store.getName());
                    try {
                        editor.putString("usersStores", ObjectSerializer.serialize(stores_objects));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }

                Log.d("LoSeSANO", "Size: " + stores_objects.size());

                Intent intent2 = new Intent(this, LoggedInActivity.class);
                startActivity(intent2);
                break;
        }
    }
}

下面是我尝试接收SP对象的代码

package com.mad.losesano2;

import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.io.IOException;
import java.util.ArrayList;

public class LoggedInActivity extends AppCompatActivity {


    ArrayList<Store> store_list;
    SharedPreferences sp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_logged_in);

        if (null == store_list) {
            store_list = new ArrayList<Store>();
        }

        sp = getSharedPreferences("storeList", MODE_PRIVATE);

        try {
            store_list = (ArrayList<Store>) ObjectSerializer.deserialize(sp.getString("usersStores", ObjectSerializer.serialize(new ArrayList<Store>())));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
       Log.d("LoSeSANO", "Store name  at index 0: " + store_list.get(0).getName()); //store_list size = 0.
    }
}

最后,这里是ObjectSerializer类

package com.mad.losesano2;

/**
 * Created by oshau on 18/03/2018.
 */

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectSerializer {

    public static String serialize(Serializable obj) throws IOException {
        if (obj == null) return "";
        ByteArrayOutputStream serialObj = new ByteArrayOutputStream();
        ObjectOutputStream objStream = new ObjectOutputStream(serialObj);
        objStream.writeObject(obj);
        objStream.close();
        return encodeBytes(serialObj.toByteArray());
    }

    public static Object deserialize(String str) throws IOException, ClassNotFoundException {
        if (str == null || str.length() == 0) return null;
        ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str));
        ObjectInputStream objStream = new ObjectInputStream(serialObj);
        return objStream.readObject();
    }

    public static String encodeBytes(byte[] bytes) {
        StringBuffer strBuf = new StringBuffer();

        for (int i = 0; i < bytes.length; i++) {
            strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
            strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
        }

        return strBuf.toString();
    }

    public static byte[] decodeBytes(String str) {
        byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < str.length(); i+=2) {
            char c = str.charAt(i);
            bytes[i/2] = (byte) ((c - 'a') << 4);
            c = str.charAt(i+1);
            bytes[i/2] += (c - 'a');
        }
        return bytes;
    }
}

共有2个答案

穆飞星
2023-03-14

我看到你只存储一个简单的列表,然后你不容易分享数据。可以使用这样的小数据:SparseBooleanArray a=list_view.getCheckedItemPosition();

我将创建一个类

Class A implement Serializable{
   List<String> data;
}

然后通过Intent发送Serializable。

宗涵蓄
2023-03-14
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mad.losesano2/com.mad.losesano2.LoggedInActivity}: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

从这个日志猫可以清楚地看出,您的数组大小是0,您正在尝试访问索引0。确保在访问其内容之前检查数组长度。

也许你会因为这条线而崩溃

 Log.d("LoSeSANO", "Store name  at index 0: " + store_list.get(0).getName());

检查store_list大小之前访问它的索引。

 类似资料:
  • 我有一个由ArrayList组成的疯狂结构,每个项目都包含一个ArrayList of Object。这些对象可以是长数组或字符串。我需要序列化这个疯狂的结构,但无法实现我的目标。之后反序列化怎么样?我了解序列化和反序列化的基础知识,但不确定这样的结构。非常感谢您的帮助。 我的作品: Object类型的“ohs”应该始终是ArrayList,我发现它应该已经可以序列化了,但我想它并没有那么简单

  • 我想在java中序列化并保存一个包含双[]数组列表的数组列表。这是我的代码。 但我得到一个错误,下面是堆栈跟踪。 java线程“AWT-EventQueue-0”中出现异常。java上的lang.NullPointerException。伊奥。ObjectOutputStream$BlockDataOutputStream。java上的drain(未知源代码)。伊奥。ObjectOutputStr

  • 我正在尝试使用put方法将arraylist存储在hashmap中。我在下一步中清除了列表,以便在下一次迭代中添加下一组值。一旦清除列表,地图中的值也会被清除。虽然我在清理清单之前已经把清单放在地图上了。 sysout打印{key=[]} 有人请让我清楚如何坚持hashmaphash地图。

  • 问题内容: 我想序列化Arraylist类型 ,并且该类包含两个原始类型的Arraylist 我怎样才能做到这一点? 提前非常感谢 问题答案: 如果要使用Serializable,应该没有问题,因为ArrayList就像String和每个基本类型一样都是Serializable的。应该做。您可以在此处阅读有关此方法的更多信息。但是,还有许多其他序列化选项。因此,请更具体。

  • 我的项目是关于图书馆管理系统的。我必须将数据存储到类的对象中,然后将它们存储到ArrayList中。然后我在序列化数据。 我有这些功能: null 我用来反序列化的代码: 我得到了一个异常,因为BufferedReader需要是瞬态的,这是修复的。但现在,我认为我的序列化不起作用了。每次我创建一本书,我都将它的索引(对象编号)存储在一个文本文件中。我的搜索技术都不起作用:ArrayIndexOut

  • 假设序列化。bin是一个充满单词的文件,在序列化时是ArrayList 我希望能够反序列化“serialise.bin”文件并将内容存储在ArrayList中