張紹文android開發高手課讀書筆記5-數據存儲篇

本系列博文 基於是前微信高級工程師張紹文專欄 《Android開發高手課》的讀書筆記。

文章所寫內容是本人讀完的感悟,需要原文的朋友請自行購買。

存儲優化篇

Android分區

分區簡單來說就是將設備中的存儲劃分爲一些互不重疊的部分,每個部分都可以單獨格式化,用作不同的目的。

  • /system: 操作系統預留,用來存儲系統文件和框架的,系統升級和恢復時會擦除這一整塊分區
  • /data: 用來存儲用戶數據的地方,手機上恢復出廠設置的那個操作就只會擦除這部分數據
  • /cache: 系統升級或者恢復時的備用分區
  • /vendor: 用來存放手機廠商對Android系統的修改
  • /storge: 內置或者外置的sdcard

數據存儲需要考慮哪些要素

數據存儲就是把特定的數據結構轉化成可以被記錄和還原的格式,這個數據格式可以是二進制的,也可以是 XML、JSON、Protocol Buffer 這些格式。

在選擇數據存儲的時候需要考慮的要素

數據存儲的選項

  • SharedPreferences
  • ContentProvider
  • 文件
  • 數據庫

SharedPreferences

使用場景

用於存儲一些非常簡單,輕量的數據。

優點

  • 系統支持,使用簡單
  • 兼容性強

缺點

  • 跨進程不安全
  • 加載緩慢。SharedPreferences 文件的加載使用了異步線程,而且加載線程並沒有設置線程優先級,如果這個時候主線程讀取數據就需要等待文件加載線程的結束
  • 全量寫入。無論是調用 commit() 還是 apply(),即使我們只改動其中的一個條目,都會把整個內容全部寫到文件。而且即使我們多次寫入同一個文件,SP 也沒有將多次修改合併爲一次,這也是性能差的重要原因之一。

基於以上原因,各大公司都會有對應的一個替代的存儲方案,比如微信的MMKV

ContentProvider

使用場景

跨進程,跨應用程序之間的大數據量交互,總體來說ContentProvider的整體框架還是不錯的,目前市面上好像也沒有什麼自研的架構替代。

需要注意的點

ContentProvider 的生命週期默認在 Application onCreate() 之前,而且都是在主線程創建的。我們自定義的 ContentProvider 類的構造函數、靜態代碼塊、onCreate 函數都儘量不要做耗時的操作,會拖慢啓動速度。

對象的序列化

Serializable

java原生的序列化機制,其本身是通過 ObjectInputStream 和 ObjectOutputStream 來實現的,由於在序列化過程中使用了大量的反射和臨時變量使得性能下降,文件體積變大。

需要注意的點

  • 不被序列化的字段。類的 static 變量以及被聲明爲 transient 的字段,默認的序列化機制都會忽略該字段,不會進行序列化存儲。當然我們也可以使用進階的 writeReplace 和 readResolve 方法做自定義的序列化存儲。
  • serialVersionUID。在類實現了 Serializable 接口後,我們需要添加一個 Serial Version ID,它相當於類的版本號。這個 ID 我們可以顯式聲明也可以讓編譯器自己計算。通常我建議顯式聲明會更加穩妥,因爲隱式聲明假如類發生了一點點變化,進行反序列化都會由於 serialVersionUID 改變而導致 InvalidClassException 異常。
  • 構造方法。Serializable 的反序列默認是不會執行構造函數的,它是根據數據流中對 Object 的描述信息創建對象的。如果一些邏輯依賴構造函數,就可能會出現問題,例如一個靜態變量只在構造函數中賦值,當然我們也可以通過進階方法做自定義的反序列化修改。

Parcelable

主要解決Serializable性能低下的問題。

使用Parcelable比Serializable需要多添加一些自定義代碼,正是因爲這些代碼,使得Parcelable在序列化的時候不需要採用大量反射這種耗時的行爲,從而提高性能。

需要注意的點

使用Parcelable進行永久存儲的話,會存在一些問題。

  • 系統版本的兼容性。由於 Parcelable 設計本意是在內存中使用的,我們無法保證所有 Android 版本的Parcel.cpp實現都完全一致。如果不同系統版本實現有所差異,或者有廠商修改了實現,可能會存在問題。
  • 數據前後兼容性。Parcelable 並沒有版本管理的設計,如果我們類的版本出現升級,寫入的順序及字段類型的兼容都需要格外注意,這也帶來了很大的維護成本。

一般來說,如果需要持久化存儲的話,一般還是不得不選擇性能更差的 Serializable 方案。

Serial

Twitter開源的Serial保留了Serializable和Parcelable的大部分優點

[圖片上傳失敗...(image-b41fc9-1550743598127)]

數據的序列化

Serial 性能看起來還不錯,但是對象的序列化要記錄的信息還是比較多,在操作比較頻繁的時候,對應用的影響還是不少的,這個時候我們可以選擇使用數據的序列化。

JSON

優點

  • 相比對象序列化方案,速度更快,體積更小。
  • 相比二進制的序列化方案,結果可讀,易於排查問題。
  • 使用方便,支持跨平臺、跨語言,支持嵌套引用。

市面上可用的框架有Android自帶的JSON庫,Google的Gson,阿里的FastJson,美團的MSON

總的來說Gson的兼容性最好,數據量極大時,FastJson的性能最佳。

Protocol Buffers

二進制序列化方案,數據量龐大的時候性能優於JSON,

數據庫優化

推薦使用自帶的SQLite,Realm或者Google的LevelDB。

這部分內容在張老師文中提到的多是線程併發,索引優化,page和緩存處理等。比較深,這裏就不提了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章