zoukankan      html  css  js  c++  java
  • 一起学Android之Storage

    概述

    在Android开发中,存储(Storage)的方式根据具体的需求不同而不同,例如数据对应用程序是私有的还是其他应用程序(和用户)可以访问的,以及保存数据需要多大的空间。

    存储分类

    主要的存储方式有以下几种(本文主要涉及前三种):

    1. Shared Preferences:以键值对( key-value pairs)的方式存储在程序内部;
    2. Internal Storage:将数据保存在设备内存中;
    3. External Storage:将公有数据保存在外部存储中(SD卡);
    4. SQLite Databases:保存结构化数据到私有数据库中;
    5. Network Connection:通过网络服务器,将数据存储在web上。

    涉及知识点

    涉及的知识点如下:

    1. SharedPreferences 共享目录接口,通过Context中的getSharedPreferences进行实例化。
    2. SharedPreferences.Editor 共享目录编辑器,需要以commit进行保存。
    3. FileOutputStream 文件输出流,用write方法将数据保存文件。
    4. FileInputStream 文件输入流,用于读取文件的内容,通过Context中的openFileInput进行实例化,用read方法进行读取内容。
    5. deleteFile Context中的方法,删除指定路径的文件
    6. Environment.getExternalStorageDirectory() 获取外部存储的根目录。
    7. Environment.getExternalStorageState() 获取外部存储卡的状态。
    8. File.separator 文件路径分割符,用斜杠(/)进行表示。
    9. BitmapFactory.decodeResource(getResources(), R.drawable.bg) 通过资源文件实例化对象。
    10. BitmapFactory.decodeFile(imgFile.getAbsolutePath() 通过具体文件的路径实例化对象。
    11. File 文件对象,mkdirs() 创建多层目录 mkdirs创建单个目录,exists() 判断文件或目录是否存在,createNewFile() 创建新文件。

    Shared Preferences

    此种方式,只能保存简单的数据类型如下图所示:

    代码如下:

     1     /**
     2      * SharedPreferences保存
     3      * @param v
     4      */
     5     public void sharedSave(View v){
     6         String name=etName.getText().toString().trim();
     7         String age=etAge.getText().toString().trim();
     8         if(TextUtils.isEmpty(name)||TextUtils.isEmpty(age)){
     9             return;
    10         }
    11         //构造一个编辑器----笔
    12         SharedPreferences.Editor editor = sp.edit();
    13         //数据的存储---只能存储简单的数据
    14         editor.putString("name",name);
    15         editor.putString("age",age);
    16         //提交--保存
    17         editor.commit();
    18         //清空
    19         etName.setText("");
    20         etAge.setText("");
    21     }
    22 
    23     /**
    24      * SharedPreferences读取
    25      */
    26     public void sharedRedo(View v){
    27         String name=sp.getString("name","");
    28         String age=sp.getString("age","");
    29         etName.setText(name);
    30         etAge.setText(age);
    31     }

    Internal Storage

    将数据内容转换为字节的方式保存在文件中,如下图所示:

    代码如下:

     1     /**
     2      * 内部保存
     3      * @param v
     4      */
     5     public void internalSave(View v) {
     6         String name = etName.getText().toString().trim();
     7         String age = etAge.getText().toString().trim();
     8         if (TextUtils.isEmpty(name) || TextUtils.isEmpty(age)) {
     9             return;
    10         }
    11 
    12         try {
    13             String content = "这是我的姓名:" + name + "这是我的年龄:" + age;
    14             FileOutputStream fos = openFileOutput(sname, MODE_PRIVATE);
    15             fos.write(content.getBytes());
    16             fos.close();
    17             etName.setText("");
    18             etAge.setText("");
    19         } catch (IOException e) {
    20             e.printStackTrace();
    21         }
    22     }
    23 
    24     /**
    25      * 内部读取
    26      * @param v
    27      */
    28     public void internalRedo(View v) {
    29         try {
    30             FileInputStream fis = openFileInput(sname);
    31             byte[] buffer = new byte[fis.available()];
    32             fis.read(buffer);
    33             fis.close();
    34             String content = new String(buffer);
    35             Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
    36         } catch (IOException e) {
    37             e.printStackTrace();
    38         }
    39     }
    40 
    41     /**
    42      * 删除文件
    43      * @param v
    44      */
    45     public void internalDel(View v){
    46         boolean del=deleteFile(sname);
    47         if(del){
    48             Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();
    49         }else{
    50             Toast.makeText(this, "删除失败", Toast.LENGTH_SHORT).show();
    51         }
    52     }

    External Storage

    在外部存储中,需要在AndroidManifest.xml中配置相关的读写权限,如下所示:

    1   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"  />
    2     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    3     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    保存在SD卡中,如下图所示:

    代码如下:

     1     /**
     2      * 外部存储
     3      * @param v
     4      */
     5     public void externalSave(View v) {
     6 
     7         try {
     8             Log.i(TAG, "externalSave: 开始");
     9             Bitmap img = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
    10             ByteArrayOutputStream bass = new ByteArrayOutputStream();
    11             img.compress(Bitmap.CompressFormat.JPEG, 100, bass);
    12             img.recycle();
    13             Log.i(TAG, "externalSave: saveImg");
    14             boolean saveOk = saveImg("dog.jpg", bass.toByteArray());
    15             Log.i(TAG, "externalSave: saveImg:"+saveOk);
    16             if (saveOk) {
    17                 Toast.makeText(this, "保存成功", Toast.LENGTH_SHORT).show();
    18             }
    19             bass.close();
    20             Log.i(TAG, "externalSave: 结束");
    21         } catch (IOException e) {
    22             e.printStackTrace();
    23             Log.i(TAG, "externalSave: 异常"+e.getMessage());
    24         }
    25     }
    26 
    27     /**
    28      * 外部读取
    29      * @param v
    30      */
    31     public void externalRedo(View v) {
    32         if (!isMounted()) {
    33             return;
    34         }
    35         try {
    36             Bitmap img = readImg("dog.jpg");
    37             iv01.setImageBitmap(img);
    38         } catch (Exception e) {
    39             e.printStackTrace();
    40         }
    41     }
    42 
    43     private boolean saveImg(String fileName,byte[] data){
    44         Log.i(TAG, "saveImg: 开始");
    45         if(!isMounted()){
    46             Log.i(TAG, "saveImg: 挂载失败");
    47             return false;
    48         }
    49         Log.i(TAG, "saveImg: 路径:"+storedPath);
    50         File dir=new File(storedPath);
    51         if(!dir.exists()){
    52            boolean f= dir.mkdirs();
    53             if(f){
    54                 Log.i(TAG, "saveImg: 创建目录成功:"+storedPath);
    55             }else{
    56                 Log.i(TAG, "saveImg: 创建目录失败:"+storedPath);
    57             }
    58         }
    59         Log.i(TAG, "saveImg: 判断路径:ok");
    60         try {
    61             File file=new File(storedPath,fileName);
    62             if(file.exists()){
    63                 Log.i(TAG, "saveImg: 判断文件:1");
    64                 file.delete();
    65             }
    66             Log.i(TAG, "saveImg: 判断文件:2");
    67             file.createNewFile();
    68             Log.i(TAG, "saveImg: 判断文件:ok");
    69             FileOutputStream fos=new FileOutputStream(file);
    70             fos.write(data);
    71             fos.close();
    72             return true;
    73         } catch (IOException e) {
    74             e.printStackTrace();
    75             Log.i(TAG, "saveImg: 异常:"+e.getMessage());
    76             return false;
    77         }
    78     }
    79 
    80     public Bitmap readImg(String fileName){
    81         if(!isMounted()){
    82             return null;
    83         }
    84         File imgFile=new File(storedPath,fileName);
    85         if(imgFile.exists()){
    86             return BitmapFactory.decodeFile(imgFile.getAbsolutePath());
    87         }
    88         return null;
    89     }
    90 
    91     private  boolean isMounted(){
    92         String state=Environment.getExternalStorageState();
    93         return  state.equals(Environment.MEDIA_MOUNTED);
    94     }


    备注

    在进行外部存储时,如果默认关闭了APP的存储空间权限,没有前往设置开启应用权限,即使manifest中正常注册权限,该APP仍让无法读写文件。调试日志如下:

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    未开启App的存储权限
    04-02 21:21:59.173 30863-30863/com.hex.demostorage I/DemoStorage: externalSave: 开始
    04-02 21:21:59.407 30863-30863/com.hex.demostorage I/DemoStorage: externalSave: saveImg
    04-02 21:21:59.408 30863-30863/com.hex.demostorage I/DemoStorage: saveImg: 开始
    04-02 21:21:59.412 30863-30863/com.hex.demostorage I/DemoStorage: saveImg: 路径:/storage/emulated/0/hex/images
    04-02 21:21:59.412 30863-30863/com.hex.demostorage I/DemoStorage: saveImg: 判断路径:ok
    04-02 21:21:59.412 30863-30863/com.hex.demostorage I/DemoStorage: saveImg: 判断文件:2
    04-02 21:21:59.414 30863-30863/com.hex.demostorage I/DemoStorage: saveImg: 异常:No such file or directory
    04-02 21:21:59.414 30863-30863/com.hex.demostorage I/DemoStorage: externalSave: saveImg:false
    04-02 21:21:59.414 30863-30863/com.hex.demostorage I/DemoStorage: externalSave: 结束
    开启App的存储权限
    04-02 21:22:48.519 31306-31306/com.hex.demostorage I/DemoStorage: externalSave: 开始
    04-02 21:22:48.754 31306-31306/com.hex.demostorage I/DemoStorage: externalSave: saveImg
    04-02 21:22:48.755 31306-31306/com.hex.demostorage I/DemoStorage: saveImg: 开始
    04-02 21:22:48.759 31306-31306/com.hex.demostorage I/DemoStorage: saveImg: 路径:/storage/emulated/0/hex/images
    04-02 21:22:48.760 31306-31306/com.hex.demostorage I/DemoStorage: saveImg: 判断路径:ok
    04-02 21:22:48.760 31306-31306/com.hex.demostorage I/DemoStorage: saveImg: 判断文件:2
    04-02 21:22:48.761 31306-31306/com.hex.demostorage I/DemoStorage: saveImg: 判断文件:ok
    04-02 21:22:48.763 31306-31306/com.hex.demostorage I/DemoStorage: externalSave: saveImg:true
    04-02 21:22:48.787 31306-31306/com.hex.demostorage I/DemoStorage: externalSave: 结束

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    记录学习,记录成长!

  • 相关阅读:
    基于sshpass批量实现主机间的key验证脚本
    一键安装mysql5.7.30脚本
    centos8网卡名称修改
    mysql分库备份脚本
    centos一键二进制编译安装mariadb-10.2.31脚本
    chrony时间同步服务简介及配置
    linux基于key验证
    expect 脚本语言中交互处理常用命令
    shell中数值测试和算术表达式比较
    JAVA Math的简单运用
  • 原文地址:https://www.cnblogs.com/hsiang/p/10645965.html
Copyright © 2011-2022 走看看