SharedPreferences和保存成文件哪个好?

请问一下,我想将自定义的layout文件做一个持久化,目的是关闭app都将当前界面状态保存,然后打开app时恢复上次关闭时的状态。
自己定义layout中有button和imagebutton 、 textview,将这几个控件当做一整个view。需要放入多个那种view时,这个layout是否算复杂?因为看到说SharedPreferences用的时候layout不要太复杂。想问一下是用SharedPreferences好还是写入文件好?

SharedPreferences和保存成文件都可以实现持久化数据的功能,但是每种方式适用的场景不同。

SharedPreferences主要适用于存储键值对的简单数据,比如存储一些用户的偏好设置,比如是否允许推送通知,是否开启自动登录等等。这些数据量较小,可以存储在SharedPreferences中。但需要注意的是,SharedPreferences只适用于存储少量简单的数据,复杂的数据结构不适合使用SharedPreferences存储。

保存成文件适用于存储复杂的数据结构和大量数据,比如存储应用程序的配置、缓存、日志等。对于存储具有大量结构的数据,例如多个控件的布局,我们可以考虑将其序列化后以文件形式存储。

回到上述情况,由于自定义的layout中有button和imagebutton、textview等多个控件,每个控件又包含一些属性,所以这种情况下建议使用保存成文件的方式。当我们关闭app时,读取相关文件内容并反序列化即可恢复上次保存的状态。

例子:将多个控件的布局相应的Java对象中,将该对象序列化并写入文件中。当我们再次打开app时,从文件中读取序列化对象,解析其数据并恢复视图的状态。

需要注意的是,如果保存的数据量过大或者保存的数据结构比较复杂,会对程序读写操作和占用存储空间产生一定的影响,需要合理地处理保存数据的方式。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    答案:

    为实现持久化保存自定义的layout文件的状态,可以将layout文件中每一个控件的状态都保存到SharedPreferences或文件中,然后在下次打开app时读取SharedPreferences或文件来恢复之前关闭时的状态。具体的步骤如下:

    1. 在Activity中重写onSaveInstanceState(Bundle savedInstanceState)方法,将需要保存的控件的状态保存到Bundle savedInstanceState中。例如:
    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putBoolean("Button1_enabled", button1.isEnabled());
        savedInstanceState.putInt("ImageButton1_image", ((BitmapDrawable)imageButton1.getDrawable()).getBitmap().getGenerationId());
        savedInstanceState.putString("TextView1_text", textView1.getText().toString());
    }
    
    1. 在Activity中重写onRestoreInstanceState(Bundle savedInstanceState)方法,将之前保存在Bundle savedInstanceState中的控件状态恢复。例如:
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        button1.setEnabled(savedInstanceState.getBoolean("Button1_enabled"));
        imageButton1.setImageResource(savedInstanceState.getInt("ImageButton1_image"));
        textView1.setText(savedInstanceState.getString("TextView1_text"));
    }
    
    1. 如果需要在关闭app后仍能保留控件状态,可以将控件状态保存到SharedPreferences或文件中。SharedPreferences可以轻松地保存少量数据,而保存大量数据则不太适合。因此,如果要保存大量数据,最好将数据保存到文件中。例如:

    保存到SharedPreferences:

    SharedPreferences.Editor editor = getSharedPreferences("MyPrefs", MODE_PRIVATE).edit();
    editor.putBoolean("Button1_enabled", button1.isEnabled());
    editor.putInt("ImageButton1_image", ((BitmapDrawable)imageButton1.getDrawable()).getBitmap().getGenerationId());
    editor.putString("TextView1_text", textView1.getText().toString());
    editor.apply();
    

    读取SharedPreferences:

    SharedPreferences prefs = getSharedPreferences("MyPrefs", MODE_PRIVATE);
    button1.setEnabled(prefs.getBoolean("Button1_enabled", true));
    imageButton1.setImageResource(prefs.getInt("ImageButton1_image", 0));
    textView1.setText(prefs.getString("TextView1_text", ""));
    

    保存到文件:

    FileOutputStream outputStream = null;
    try {
        outputStream = openFileOutput("layout_state.txt", MODE_PRIVATE);
        outputStream.write(("Button1_enabled=" + button1.isEnabled() + "\n").getBytes());
        outputStream.write(("ImageButton1_image=" + ((BitmapDrawable)imageButton1.getDrawable()).getBitmap().getGenerationId() + "\n").getBytes());
        outputStream.write(("TextView1_text=" + textView1.getText().toString() + "\n").getBytes());
        outputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    读取文件:

    FileInputStream inputStream = null;
    try {
        inputStream = openFileInput("layout_state.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] keyValue = line.split("=");
            if (keyValue.length == 2) {
                if (keyValue[0].equals("Button1_enabled")) {
                    button1.setEnabled(Boolean.parseBoolean(keyValue[1]));
                } else if (keyValue[0].equals("ImageButton1_image")) {
                    imageButton1.setImageResource(Integer.parseInt(keyValue[1]));
                } else if (keyValue[0].equals("TextView1_text")) {
                    textView1.setText(keyValue[1]);
                }
            }
        }
        inputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    1. 如果需要保存多个控件的状态,可以将它们的状态用合适的方法保存到SharedPreferences或文件中,再在读取时逐个恢复。如果控件数量过多,可以考虑使用数据库来保存状态。

    2. 如果layout中包含大量控件,可以将它们按照类型进行分组,使用多个SharedPreferences或文件来保存它们的状态,减小单个SharedPreferences或文件的数据量。但是,不要将过于复杂的layout保存到SharedPreferences中。这种情况下最好将状态保存到文件中。

    最后,需要注意的是,保存控件状态的方法应该在合适的时机调用,例如在控件状态改变时、Activity生命周期结束时、系统即将销毁Activity时等。如果使用SharedPreferences或文件保存状态,需要在Activity的onPause()或onStop()方法中调用保存方法。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^