三維角度觀察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開銷
相關文章
相關標籤/搜索