Android笔记—数据保存


资料来源如下

  • 第一行代码(第二版)

编程环境

  • Android Studio 2.2.3

Android 中的主要数据存储

  • 有三种

  • 保存键值集
    要保存的相对较小键值集合,使用 SharedPreferences

  • 保存文件
    使用 Android 文件系统通过 File API 读取和写入文件,适合按开始到结束的顺序不跳过地读取或写入大量数据。 例如,图片文件或通过网络交换的任何内容

  • 在 SQL 数据库中保存数据
    Android内建的SQLite 数据库存储重复或结构化数据


  • PS:这里如果没有学过 SQL 数据库使用,推荐LitePal
  • Android开源数据库LitePal :郭霖(第一行代码作者)
  • 详细介绍在这里(懒人必备)Android开源数据库LitePal

保存键值集

  • 想要保存的相对较小键值集合

  • 调用SharedPreferences

  • 首先:获取SharedPreferences的句柄
    用户可以创建一个共享参数文件或访问一个已经存在的共享参数文件。
    具体途径有三条

    • getSharedPreferences (String name, int mode)
      • 第一个参数:SharedPreferences的名称,第二个:参数指定操作模式
      • 需要创建/读取 多个共享参数文件时使用,每个文件都拥有一个标识符,可以通过这个标识符通过该方法的第一个参数获得共享参数对象。可以通过APP中的任意Context对象调用它。
      • 示例
        1
        2
        //指定SharedPreferences名称为data  模式为MODE_PRIVATE:只有当前程序才有权限读取/修改
        SharedPreferences sharedPref = getSharedPreferences("data", MODE_PRIVATE);
    • getPreferences (int mode)
      • 参数:指定操作模式
      • 只创建 Activity 的一个SharedPreferences。在Activity 中使用。 方法会检索属于该 Activity 的默认共享首选项文件,无需提供名称
      • 示例
        1
        2
        //模式:MODE_PRIVATE:只有当前程序才有权限读取/修改
        SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    • getDefaultSharedPreferences(context)
      • 参数:context
      • 自动以档期应用程序包名作为前缀命名SharedPreferences文件
  • 写入数据到共享参数中
    • SharedPreferences 调用 edit() 创建一个 SharedPreferences.Editor
      使用诸如 putInt() 和 putString() 方法写入的键和值
      最后调用commit() 以保存更改
      也可调用apply() 保存更改

  • commit() 与 apply() 相同/区别
  • 相同
    • 都是提交preference修改数据
  • 区别
    • apply没有返回值 commit返回boolean表明修改是否提交成功
    • apply是将操作提交到内存,而后异步真正提交到文件
      commit是同步的提交到文件
      多个commit同时提交,互相等待,效率较低
      apply直接覆盖,效率较高
    • apply没有任何错误提示,只是提交的动作

  • 示例
    1
    2
    3
    4
    5
    6
    //创建 .edit()
    SharedPreferences.Editor editor = sharedPref.edit();
    //写入字符串。key-值 TextView
    editor.putString("TextView","hello");
    //保存更改
    editor.commit();
  • 从共享参数中读取数据
    • 获取SharedPreferences的句柄
      方式同上
    • 调用比如getInt()或getString()方法,然后传入键值,如果键不存在,则会返回一个默认值
    • 示例
      1
      2
      3
      4
      5
      6
      //获取SharedPreferences的句柄
      SharedPreferences sharedPreferences = getSharedPreferences("data",MODE_PRIVATE);
      //读取键值对应数据
      String text = sharedPreferences.getString("TextView","");
      //打印到log中 验证
      Log.d("data",text);

保存到文件

  • Android 设备有两个文件存储区域: 内部存储 和 外部存储
    Android 设备早期内置的非易失性内存(内部存储),以及移动存储介质 微型 SD 卡等(外部存储)
    任何Android设备始终有两个存储空间,并且无论外部存储设备是否可移动,API 的行为均一致

  • Android的文件存储是以java流为基础,并优化了一些操作。java流不属于本文范围。

  • 涉及java流部分参考Android文件IO详解

内部存储

保存到内部存储

  • 某一应用对其内部存储 始终具有 进行读写的权限,而无需声明任何权限,在 Android N之前,内部文件可以通过放宽权限让其他应用访问。但是极不推荐以这种方式共享文件
  • 简单实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public void save(String inputText){
    //新建一个FileOutputStream对象(字节流)
    FileOutputStream out = null;
    //新建一个BufferedWriter (字符流)
    BufferedWriter writer = null;
    try{
    //out 实例化
    out = openFileOutput("data",Context.MODE_PRIVATE);
    //OutputStreamWrit 字节流转换为字符流
    //字符流绑定BufferedWriter(缓冲区)
    writer = new BufferedWriter(new OutputStreamWriter(out));
    //写入到文件
    writer.write(inputText);
    }catch (IOException e ){
    e.printStackTrace();
    } finally {
    try{
    //如果写入成功
    if (writer != null) {
    //关闭流
    writer.close();
    }
    }catch (IOException e){
    e.printStackTrace();
    }
    }
    }
  • FileOutputStream:

    • 继承自 OutputStream 用于文件处理的节点流
    • 用于写入原始字节流到文件
  • FileOutputStream openFileOutput (String name, int mode)

    • 返回FileOutputStream对象
    • 第一个参数是文件名
    • 第二个参数是操作模式,有4种取值
      • MODE_PRIVATE(默认)_当同一文件名存在时覆盖原文件
      • MODE_APPEND _当同名文件存在时,在原文件末尾追加
      • 其余两种均在android4.2及以上版本中废弃
  • OutputStreamWrit

    • 继承自 Writer
    • 将字节流转换为字符流
  • BufferedWriter

    • 继承自Writer
    • 绑定字符输出流,提高具体的流对象的效率
    • .flush()方法 对缓冲区进行刷新,让数据到目的地
    • .close();方法 关闭缓冲区,即关闭绑定的流
从内部存储读取文件
  • 简单实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public String load(){
    //新建FileInputStream对象
    FileInputStream in = null;
    //新建 BufferedReader对象
    BufferedReader reader = null;
    //新建一个StringBuilder 空
    content = new StringBuilder();
    try{
    //FileInputStream对象实例化
    in = openFileInput("data");
    //字节流转换为字符流
    //缓冲流绑定字符流
    reader = new BufferedReader(new InputStreamReader(in));
    //空 String
    String line = "";
    //读取文件内容,并判断是否读取完成
    while((line = reader.readLine())!=null){
    //读取内容添加到 StringBuilder 对象中
    content.append(line);
    }
    }catch (IOException e){
    e.printStackTrace();
    }
    finally {
    if(reader != null){
    try{
    //关闭流
    reader.close();
    }catch (IOException e){
    e.printStackTrace();
    }
    }
    }
    //将读取结果 由StringBuilder转换为String 并返回
    return content.toString();
    }
  • FileInputStream

    • 继承自 InputStream,用于文件处理的节点流
    • 从文件中读取
  • FileInputStream openFileInput(String filename)

    • 返回FileInputStream对象
    • 参数为 读取的文件名
  • InputStreamRead

    • 将字节流转换为字符流
  • BufferedReader

    • 缓冲流

外部存储

  • 占坑