SharedPreferences问题,覆盖

时间:2015-02-01 11:58:54

标签: android sharedpreferences

我将一些值存储在共享首选项文件中,并且在我的代码中的某个时刻,我将此文件拆分并将共享上传到多个云,以便我可以进行安全备份。

所以我的应用程序现在,当它开始时看一下共享首选项文件夹,如果这个文件不存在,它会要求用户登录云来恢复文件(想想用户失去它的情况)手机)。

因此,尝试性能,我模拟我没有这样的文件并下载部件并将它们组合起来以获得整体。文件完全恢复(我手动打开它,它有所有字段)。

但是,当我尝试在此文件中写入新值时,系统无法识别它,删除它并创建一个新值。总而言之,文件被覆盖。即使我尝试从旧文件(我下载的文件)中读取值,它也不起作用并返回默认值。

你知道可能存在什么问题吗?除了不使用共享偏好之外还有什么解决方案吗?

KeyManagement.combineFile(split);
SharedPreferences prefs = mContext.getSharedPreferences("CACSPrefs", 0);
String key = prefs.getString("KEY", null);
Editor editor = prefs.edit();
editor.putString("IS_STORED", "TRUE");
editor.commit();

split是一个Files数组(我从Internet上下载的部分)。我检查了重组文件名为“CACSPrefs.xml”

修改

当我拆分原始文件时,我逐个向每个共享发送一个字节,每个共享一个字符,但是添加“_1”,“_ 2”,...所以组合文件的行为反过来说。

protected static void combineFile(File[] fileShares) throws FileNotFoundException, IOException{

    // create file
    String parentPath = fileShares[0].getParent();
    String fileName = fileShares[0].getName().substring(0,
            fileShares[0].getName().indexOf("_"));
    File file = new File(parentPath + "/" + fileName);  
    if (!file.exists()) file.createNewFile();
    FileInputStream[] in = new FileInputStream[fileShares.length];

    // create input streams
    int length = 0;
    for (int i = 0; i < fileShares.length; i++){
        length += (int) fileShares[i].length();
        in[i] = new FileInputStream(fileShares[i].getAbsolutePath());
    }       

    // read byte by byte and write
    FileOutputStream out = new FileOutputStream(file);  
    for (int i = 0; i < length; i++){
        int b;
        if((b = in[i % fileShares.length].read()) == -1) break;
        out.write((byte) b);
    }
    out.flush();
    out.close();

    for (int i = 0; i < fileShares.length; i++){
        in[i].close();
    }
} 

1 个答案:

答案 0 :(得分:1)

我建议另一个解决方案。编写一种方法,使用标准SharedPreferences.get*()方法将您要上传到云的值转换为JSON并上传JSON。然后,当您需要它时,您将获得JSON,读取值并使用标准SharedPreferences.Editor.put*(...)方法再次存储它。

您可以避免原始代码可能导致的任何错误导致SharedPreferences无法识别该文件(或者不使用它来加载值),因为您正在使用官方访问共享偏好的方式

编辑或者不使用JSON,您可以使用您喜欢的任何传输协议,甚至是您自己的传输协议,只要您按照上述方式编写首选项。

编辑2 :OP请求此处提供了如何将选定的共享偏好设置为JSON的示例,反之亦然。

要将一些共享首选项放入JSON对象,请执行以下操作:

SharedPreferences prefs = getApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
JSONObject json = new JSONObject();

try {
  json.put("my_long", prefs.getLong("my_long", 0));
  json.put("my_string", prefs.getString("my_string", null));
  // only upload this one if it's set
  if (prefs.contains("my_boolean")) json.put("my_boolean", prefs.getBoolean("my_boolean", false));
} catch (JSONException e) {
  e.printStackTrace();
}

String toUpload = json.toString();

现在上传String toUpload,例如作为POST请求正文。

要保存从服务器获取的共享首选项,请执行以下操作:

String fromDownload =...; // obtained from http response body

try {
  SharedPreferences prefs = getApplicationContext().getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
  JSONObject json = new JSONObject(fromDownload);

  SharedPreferences.Editor editor = prefs.edit();
  // this will throw JSONException if no value came from server
  editor.putLong("my_long", json.getInt("my_long"));
  // this will set a default value if no value came from server
  editor.putString("my_string", json.optString("my_string", "default"));
  // this will only store the value if it came from server otherwise no-op
  if (json.has("my_boolean")) editor.putBoolean("my_boolean", json.getBoolean("my_boolean"));
  editor.apply();
} catch (JSONException e) {
  e.printStackTrace();
}