数据保存

保存到Preference

  • SharedPreference是Android提供的一种轻量级的数据存储方式,主要用来存储一些简单的配置信息,例如,默认欢迎语,登录用户名和密码等。其以键值对的方式存储,使得我们能很方便进行读取和存入。

  • 当有一个相对较小的key-value集合需要保存时,可以使用SharedPreferences APIs。 SharedPreferences 对象指向一个保存key-value pairs的文件,并为读写他们提供了简单的方法。每个 SharedPreferences 文件均由framework管理,其既可以是私有的,也可以是共享的。

获取SharedPreference

  • 我们可以通过以下两种方法之一创建或者访问shared preference 文件:

  • (1)getPreferences() — 当activity仅需要一个shared preference文件时。因为该方法会检索activity下默认的shared preference文件,并不需要提供文件名称。

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
  • (2)getSharedPreferences() — 如果需要多个通过名称参数来区分的shared preference文件, 名称可以通过第一个参数来指定。可在app中通过任何一个Context 执行该方法。
Context context = getActivity();
SharedPreferences sharedPref = context.getSharedPreferences(
        getString(R.string.preference_file_key), Context.MODE_PRIVATE);

注:如果创建了一个MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE 模式的shared preference文件,则其他任何app均可通过文件名访问该文件。设置为MODE_PRIVATE,该文件仅能被我们的app访问。

写Shared Preference

  • 为了写shared preferences文件,需要通过执行edit()创建一个 SharedPreferences.Editor。
  • 通过类似putInt()与putString()等方法传递keys与values,接着通过commit() 提交改变.
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();

读Shared Preference

  • 为了从shared preference中读取数据,可以通过类似于 getInt() 及 getString()等方法来读取。在那些方法里面传递我们想要获取的value对应的key,并提供一个默认的value作为查找的key不存在时函数的返回值。如下:
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.string.saved_high_score_default);
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), default);

保存到文件

  • File 对象非常适合于流式顺序数据的读写。如图片文件或是网络中交换的数据等。

存储在内部还是外部

  • 所有的Android设备均有两个文件存储区域:”internal” 与 “external” 。 这两个名称来自于早先的Android系统,当时大多设备都内置了不可变的内存(internal storage)及一个类似于SD card(external storage)这样的可卸载的存储部件。之后有一些设备将”internal” 与 “external” 都做成了不可卸载的内置存储,虽然如此,但是这一整块还是从逻辑上有被划分为”internal”与”external”的。只是现在不再以是否可卸载进行区分了。 下面列出了两者的区别:

  • Internal storage:
    总是可用的。
    这里的文件默认只能被我们的app所访问。
    当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。
    Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。

  • External storage:
    并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。
    是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。
    当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。
    External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。

注尽管app是默认被安装到internal storage的,我们还是可以通过在程序的manifest文件中声明android:installLocation 属性来指定程序安装到external storage。

保存到Internal Storage

  • getFilesDir() : 返回一个File,代表了我们app的internal目录。

  • getCacheDir() : 返回一个File,代表了我们app的internal缓存目录。请确保这个目录下的文件能够在一旦不再需要的时候马上被删除,并对其大小进行合理限制,例如1MB 。系统的内部存储空间不够时,会自行选择删除缓存文件。

  • 存、取、删除

    public static void saveLoginData(Context context, LoginData data) {
        File file = new File(context.getFilesDir(), LOGIN_URI_DATAS);
        if (file.exists()) {
            file.delete();
        }
        try {
            ObjectOutputStream oos = new ObjectOutputStream(
                    context.openFileOutput(LOGIN_URI_DATAS, Context.MODE_PRIVATE));
            oos.writeObject(data);
            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static LoginData loadLoginData(Context context) {
        LoginData data = null;
        File file = new File(context.getFilesDir(), LOGIN_URI_DATAS);
        if (file.exists()) {
            try {
                ObjectInputStream ois = new ObjectInputStream(
                        context.openFileInput(LOGIN_URI_DATAS));
                data = (LoginData) ois.readObject();
                ois.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return data;
    }
    public static void deleteLoginData(Context context){
        File file = new File(context.getFilesDir(), LOGIN_URI_DATAS);
        if (file.exists()){
            file.delete();
        }
    }
  • 如果需要缓存一些文件,可以使用createTempFile()。例如:下面的方法从URL中抽取了一个文件名,然后再在程序的internal缓存目录下创建了一个以这个文件名命名的文件。
public File getTempFile(Context context, String url) {
    File file;
    try {
        String fileName = Uri.parse(url).getLastPathSegment();
        file = File.createTempFile(fileName, null, context.getCacheDir());
    catch (IOException e) {
        // Error while creating file
    }
    return file;
}

保存文件到External Storage

  • 因为external storage可能是不可用的,比如遇到SD卡被拔出等情况时。因此在访问之前应对其可用性进行检查。我们可以通过执行 getExternalStorageState()来查询external storage的状态。若返回状态为MEDIA_MOUNTED, 则可以读写。示例如下:
 /* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}
  • 注:当用户卸载我们的app时,android系统会删除以下文件:
    所有保存到internal storage的文件。
    所有使用getExternalFilesDir()方式保存在external storage的文件。
    然而,通常来说,我们应该手动删除所有通过 getCacheDir() 方式创建的缓存文件,以及那些不会再用到的文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值