Android SharedReferences问题,覆盖

Android SharedReferences问题,覆盖,android,sharedpreferences,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是一个文件数组(我从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();
    }
} 
受保护的静态void组合文件(文件[]fileShares)抛出FileNotFoundException、IOException{
//创建文件
字符串parentPath=fileShares[0]。getParent();
字符串文件名=文件共享[0]。getName()。子字符串(0,
文件共享[0].getName().indexOf(“”);
File File=新文件(parentPath+“/”+文件名);
如果(!file.exists())file.createNewFile();
FileInputStream[]in=newfileinputstream[fileShares.length];
//创建输入流
整数长度=0;
for(int i=0;i
我建议另一种解决方案。编写一个方法,使用标准的
SharedReferences.get*()
方法仅将要上载到云的值转换为JSON,然后上载JSON。然后,当您需要它时,您将获得JSON,读取值并使用标准的
SharedReferences.Editor.put*(…)
方法再次存储它

由于您使用的是访问共享首选项的正式方式,因此可以避免原始代码可能引入的任何错误,这些错误导致
SharedReferences
无法识别该文件(或不使用它加载值)

编辑:或者不使用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 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();
}
现在上传
字符串toUpload
,例如作为POST请求正文

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

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

尝试editor.apply()而不是editor.commit(),结果相同。问题是系统无法识别该文件。在代码中,字符串键返回为null。我可以看看combineFile函数吗?当然可以!最后,我编辑了这个问题,不可能替换文件,但是你可以只更新值,我知道你有不同的类型需要注意,但这是我唯一能想到的,我从来没有用过。你能给我看一段代码吗?一些
SharedReferences
到JSON的转换?是的,这就是我的意思。在得到我想要保存的所有字符串(a、b、c和d)之后,下一步是什么?