如何在android中的共享首选项中存储2维数组或序列化它

时间:2014-04-24 06:36:52

标签: android serialization sharedpreferences

i am developing an android app where i have to save dates (* as given in array)
i am doing this by using shared preferences 
my code is working fine but it do some different behaviour which i dont know why
  a.> when i am saving array in shared prefrences it works perfect as i want but 
  b.> when it comes to fetching data it keeps single date  if the date occurs twice in      array ex.. 24 occurs 2 times in my array but on fetching it show me single 24
  c.> also it gives me unordered representation of array 

 i dont know why this is happening and how to solve it 
 **some one told me to use serialize but i dont know how to do this? **    
    String[][] my_date;
    my_date = new String[][] {
                {"14","26"},
                {"12","16","24","27"},
                {"17"},
                {"8","13","18"},
                {"14"},
                {},
                {"29"},
                {"15","18"},
                {},
                {"2","3","6","8","23"},
                {"4","6","24"},
                {}
        };

    /* storing the data in shared preferences */
        SharedPreferences pref = arg0.getSharedPreferences("MyPref", 0); // 0 - for private mode
        SharedPreferences.Editor editor = pref.edit();

            Set<String> set = new HashSet<String>();
               for(int i=0; i<my_date.length;i++){
                   for(int j =0; j<my_date[i].length;j++){
                       set.add("'"+my_date[i][j]+"'"); 
                       Log.v("dates",my_date[i][j]);
                   }
               }
               editor.putStringSet("dates", set);
               editor.commit();

/* fetching saved data */
     set=pref.getStringSet("dates", set);
     Log.v("dates",set+"----"+set.size());  

1 个答案:

答案 0 :(得分:0)

首先:这是一个坏主意。您可能更愿意以某种方式存储内容,以便您可以对其进行部分编辑,例如。比如使用自己的自定义SQLLite数据库。

但是如果您对hacky方法很好,并且想要将该多维数组存储在共享首选项中,则可能只需将其序列化为字符串并将该字符串存储在共享首选项中。

您可能只是从这个如何将事物序列化为字符串的示例中借用一些内容: Reliably convert any object to String and then back again

然后取出该字符串并将其存储在共享的首选项中。

编辑哦好吧,我很好奇所以我试了一下..我实际上发现我必须对字符串进行base64编码,我希望我能以一种有凝聚力的方式解释为什么但这大致就是我所做的:

private void mySharedPreferencesThing() {
    String[][] before = new String[][] {{"1","2","3"}, {}, {"4","5","6"}};

    System.out.println("String thing before: " + arrayToString(before));

    SharedPreferences sp = getSharedPreferences("lolcats", MODE_PRIVATE);
    String[][] after = null;
    try {
        sp.edit().putString("cats", twoDimensionalStringArrayToString(before)).commit();
        after = stringToTwoDimensionalStringArray(sp.getString("cats", null));
    } catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println("String thing after: " + arrayToString(after));
}

// Just for debugging and knowing that it looks correct - there may be
// something built in to do this
private String arrayToString(String[][] arr) {
    StringBuilder sb = new StringBuilder();
    sb.append("{\n");
    for (int i = 0; i < arr.length; i++) {
        sb.append("\t{" + TextUtils.join(", ", arr[i]) + "}");
        if (i != arr.length - 1) { sb.append(","); }
        sb.append("\n");
    }
    sb.append("}");
    return sb.toString();
}

private String twoDimensionalStringArrayToString(String[][] s) throws UnsupportedEncodingException, IOException {
    ByteArrayOutputStream bo = null;
    ObjectOutputStream so = null;
    Base64OutputStream b64 = null;
    try {
        bo = new ByteArrayOutputStream();
        b64 = new Base64OutputStream(bo, Base64.DEFAULT);
        so = new ObjectOutputStream(b64);
        so.writeObject(s);
        return bo.toString("UTF-8");
    } finally {
        if (bo != null) { bo.close(); }
        if (b64 != null) { b64.close(); }
        if (so != null) { so.close(); }
    }
}

private String[][] stringToTwoDimensionalStringArray(String s) throws ClassNotFoundException, IOException {
    ByteArrayInputStream bi = null;
    ObjectInputStream si = null;
    Base64InputStream b64 = null;
    try {
        byte b[] = s.getBytes("UTF-8"); 
        bi = new ByteArrayInputStream(b);
        b64 = new Base64InputStream(bi, Base64.DEFAULT);
        si = new ObjectInputStream(b64);
        return (String[][]) si.readObject();
    } finally {
        if (bi != null) { bi.close(); }
        if (b64 != null) { b64.close(); }
        if (si != null) { si.close(); }
    }
}