三维角度观察Android存储体系

本文部分材料参考 <<Android开发高手课>><<爱上Android>>数组

   任何一个程序,其实说白了就是不停的和数据打交道,数据持久化就是指那些内存中的瞬时数据保存到存储设备中,保证即便手机关机状况下,这些数据仍然不会丢失.安全

分类

   Android 中有 5种存储方式网络

一.sp

使用场景:

  少许数据,相似应用配置信息(如:是否打开音效果,是否开启震动,解锁口令密码),严禁存储 Html,JSON,或者超大文件,对频繁修改的文件单独隔离出来多线程

核心原理:

  保存基于Xml 文件存储 的 map key-value 数据,存储文件目录路径:app

data/data/包名/shared_prefs
复制代码
注意事项:
  • apply(): 效率高,线程不安全,不能在多线程操做异步

  • commit(): 效率低,线程安全ide

  • 数据加密工具

    • 全盘加密
        4.4引入的,Android 5.0 默认打开,它会将 /data 分区的数据进行加密/解密,对性能有必定影响
    • 文件级加密
        Android7.0增长文件的加密.在这种加密模式下,将会给文件分配一个必须用户的 passcode 推导出的秘钥.特定文件被屏幕锁屏以后,直到用户下一次解锁屏幕期间都不能访问
  • 跨进程不安全
       因为没有使用跨进程的锁,sharePrefrence在跨进程频繁读取的时候,可能会致使数据所有丢失性能

  • 加载缓慢
      sp 文件加载使用了异步线程,并且加载线程没有设置优先级,若是这时主线程读取数据就须要等待文件加载线程结束大数据

  • 卡顿
      onPause,系统会强制把全部的sharePrefrence数据落地磁盘,若是落地未完成,主线程会一直阻塞,容易卡顿甚至ANR

  • 全量写入,性能差劲
       每次apply() 或者 commit() ,即便咱们修改一个文件,都会将整个内容全量写入,并且即便咱们屡次写入,sp并无将屡次修改的内容合并为一次

优化建议:
  • 数据量超100Kb,异步线程加载sp文件
  • 复写 Application 的 getSharedPreferences 方法替换系统默认实现
竞品:

 MMKV基于mmap保证数据不会丢失,Protocol Buffer 替代 Xml和 支持增量更新.原理暂时不清楚,不作过多介绍,后续会更新文章讲解内部实现机制

二.FileDir

存储路径:
  1. 手机内存

  2. SDK卡存储

    • internal SD卡

      • 老是可用
      • 文件默认只能被咱们App所访问
      • 用户卸载 App的时候,会清空App相关全部文件
      • 确保用户不会与其余App相互访问的最佳存储区域
    • external SD卡

      • 并不老是可用,当用户经过USB模式挂载外部存储器,去下挂载部分,没法对数据进行访问
      • 保存在该目录下的文件可能会被其余程序访问
      • 当咱们卸载咱们的App,系统仅会删除External根目录(getExternalFileDir)下相关文件
      • Extral是不须要严格的访问权限而且但愿这些文件可以被其余 App 所共享或者容许用户经过电脑访问最佳存储区域
保存到手机内存
  1. 方式

Java I/O

  1. 手机路径API
API 对应路径
getFileDir data/data/包名/file/
getFileDirCacheDir data/data/包名/cache/
openFileOutput data/data/包名/file/ 直接获取写入文件流对象
openFileInput data/data/包名/file/ 直接获取读取文件流对象
SD卡存储
  1. 动态声明 读写 权限

  2. 检查SD卡是否可用

    getExternalStroageState 查询SD卡的状态, 与 MEDIA_MOUNTED 作比较

  3. 公有和私有的文件路径

    • public file
    • private file
  4. 查询剩余空间

三.SQLite

  1. ORM
    • greenDAO
    • Room
    • WCDB

四.ContentProvider

  • 启动性能

   ContentProvider 的生命周期都是在 Application onCreate() 以前,并且都是在主线程建立的,它里面有一个多进程模式,经过 multiprocess 配置,这样调用进程会在本身的进程建立一个 push 进程的 Provider 实例

  • 稳定性

   ContenProvider传输利用的是Binder机制,通常来讲有必定的限制,限制在1-2M, ContentProvider 在跨进程数据传递的时候,利用Android的匿名共享内存机制,mmap的匿名共享机制是有代价的 ContenProvider 超大数据传输, 数组批量插入,会出现数据超大异常

  • 安全性

   ContentProvider 为应用数据共享提供了很好的安全机制,ContentProvider 是 exported,另外若是咱们传入的参数是一个文件路径,而后返回文件内容,这个时候也要校验合法性,否则整个应用的私有数据都有可能被别人拿到,在 intent 传递参数的时候可能常常会犯这个错误。

总结:

ContentProvider 适合传输大数据

五.Net

   对象或者数据的序列化,对象存储到内存中,若是咱们想把对象存储下来或者在网络传输,这时候就须要用到对象的序列化和反序列化了

  • 一. 对象的序列化

    • 1. Serializable
         Serializable 是 Java 原生的序列化机制,能够序列化对象持久化存储,也能够经过 Bundle 或 Serializable 的序列化数据

      • Serializable 的原理
          Serializable 是经过 ObjectInputStream 和 ObjectOutputStream 来实现的
    • 2. Parcelable

      • Parcelable 的永久存储
      • Parcelable 的注意事项
    • 3. Serial

  • 二. 数据的序列化工具

    • JSON
    • Protocol Buffers
    • GSON
    • FastJson

遇到问题

  • GC,OOM
  • 数据损坏
  • 老数据可否迁移到新数据,新数据可否在老数据降级使用
  • 数据非对称加密影响性能
  • 数据保存前用zip或lzma压缩,避免内存开销
  • I/O存储 影响内存和CPU开销
相关文章
相关标签/搜索