Android本地儲存的幾種方式
Android提供了多種選擇來儲存永久性的資料,根據不同的需求來使用不同的儲存方式,一般情況下,儲存資料的方式有下面幾種:
- SharedPreferences
- 內部儲存
- 外部儲存
- SQLite
- 網路連線
下面主要來看一下前四種資料儲存方式。
SharedPreferences
SharedPreferences(以下簡稱SP)以鍵值對形式進行儲存,資料以xml形式儲存在/data/data/專案包名/shared_prefs/xml.xml中。一般來說,SP只能儲存基本型別的資料,如:布林型別、浮點型、整形及字串,預設情況下,SP儲存的檔案是應用的私有檔案,其他應用(和使用者)不能訪問這些檔案,SP的使用方式及原始碼解析詳見:
http://blog.csdn.net/u013700502/article/details/53635499SP不支援多程序之間通訊,多程序之間使用可能會導致資料異常,替代SP的一種方式:https://github.com/grandcentrix/tray
內部儲存
直接在裝置的內部儲存中儲存檔案。預設情況下,儲存到內部儲存的檔案是應用的私有檔案,其他應用(和使用者)不能訪問這些檔案。 當用戶解除安裝應用時,這些檔案也會被移除。
String FILENAME = "hello_file.txt"; String string = "hello world!"; FileOutputStream fos = null; try { fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); fos.write(string.getBytes()); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
我們在/data/data/專案包名/files/下可以看到已經成功建立了相應檔案並且把資料寫進去了:

其他方法(都在Context類中):
-
getFilesDir() 獲取在其中儲存內部檔案的檔案系統目錄的絕對路徑。
返回路徑為:/data/data/com.xxx.xxx/files -
getDir()
在您的內部儲存空間內建立(或開啟現有的)目錄。如:
getDir("mq", Context.MODE_PRIVATE).getAbsolutePath()
返回結果:/data/data/com.xxx.xxx/app_mq , 我們看到系統自動給我們的檔名前加了”app_”
-
deleteFile()
刪除儲存在內部儲存的檔案。如:
deleteFile("mq")
刪除/data/data/com.xxx.xxx/files 目錄中對應mq的檔案,如果存在並刪除成功,返回true;反之返回false
-
fileList()
返回應用當前儲存的一系列檔案。
同樣也是列出/data/data/com.xxx.xxx/files 目錄下的所有的檔案
外部儲存
每個相容 Android 的裝置都支援可用於儲存檔案的共享“外部儲存”。 該儲存可能是可移除的儲存介質(例如 SD 卡)或內部(不可移除)儲存。 儲存到外部儲存的檔案是全域性可讀取檔案,而且,在計算機上啟用 USB 大容量儲存以傳輸檔案後,可由 使用者修改這些檔案。儲存分為兩種,一種是應用解除安裝後,儲存資料也會被刪除,一種永久儲存,即使應用被解除安裝,儲存的資料依然存在:
(1)通過context.getExternalFilesDir(null).getPath()來獲得,得到的路徑是/storage/emulated/0/Android/data/package_name/ , 當應用解除安裝後,儲存資料也會被刪除。下面一段話來自google 文件描述:
如果處理的檔案不適合其他應用使用(例如僅供自己應用使用的圖形紋理或音效),則應該通過呼叫 getExternalFilesDir() 來使用外部儲存上的私有儲存目錄。此方法還會採用 type 引數指定子目錄的型別(例如 DIRECTORY_MOVIES)。 如果您不需要特定的媒體目錄,請傳遞 null 以接收應用私有目錄的根目錄。
從 Android 4.4 開始,讀取或寫入應用私有目錄中的檔案不再需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 許可權。 因此,您可以通過新增 maxSdkVersion 屬性來宣告,只能在較低版本的 Android 中請求該許可權:
<manifest ...> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" /> ... </manifest>
注:當用戶解除安裝您的應用時,此目錄及其內容將被刪除。此外,系統媒體掃描程式不會讀取這些目錄中的檔案,因此不能從 MediaStore 內容提供程式訪問這些檔案。 同樣,不應將這些目錄用於最終屬於使用者的媒體,例如使用您的應用拍攝或編輯的照片或使用者使用您的應用購買的音樂等 — 這些檔案應儲存在公共目錄中。
- 除了context.getExternalFilesDir()之外,還有getExternalCacheDir(),檔案將儲存到/storage/emulated/0/Android/data/package_name/cache 目錄下,當檔案不再需要時,記得把快取檔案刪除。
(2)永久儲存,即使應用被解除安裝,儲存的資料依然存在,儲存路徑如:/storage/emulated/0/mDiskCache ,可以通過Environment.getExternalStorageDirectory().getAbsolutePath() + “/mDiskCache” 來獲得路徑。
-
Android N 和更高版本的應用無法按名稱共享私有檔案,嘗試共享“file://”URI 將會導致引發FileUriExposedException。 如果應用需要與其他應用共享私有檔案,則可以將 FileProvider 與 FLAG_GRANT_READ_URI_PERMISSION 配合使用。
具體請參考:
【1】https://developer.android.com/reference/android/support/v4/content/FileProvider.html
【2】http://blog.csdn.net/lmj623565791/article/details/72859156
【3】http://yifeng.studio/2017/05/03/android-7-0-compat-fileprovider/
資料庫SQLite
Android 提供了對 SQLite 資料庫的完全支援。應用中的任何類(不包括應用外部的類)均可按名稱訪問您所建立的任何資料庫。
關於SQLite的介紹、基本使用以及升級策略,請移步:
http://blog.csdn.net/u013700502/article/details/78764917網路連線
使用網路(如果可用)來儲存和檢索有關自己的網路服務的資料。 要執行網路操作,請使用以下包中的類:
• java.net.*
• android.net.*
引用
[1] Android儲存選項:
https://developer.android.com/guide/topics/data/data-storage.html#AccessingExtFiles最後給大家分享一份非常系統和全面的Android進階技術大綱及進階資料,及面試題集
想學習更多Android知識,請加入Android技術開發企鵝交流 7520 16839
進群與大牛們一起討論,還可獲取Android高階架構資料、原始碼、筆記、視訊
包括 高階UI、Gradle、RxJava、小程式、Hybrid、移動架構、React Native、效能優化等全面的Android高階實踐技術講解效能優化架構思維導圖,和BATJ面試題及答案!
群裡免費分享給有需要的朋友,希望能夠幫助一些在這個行業發展迷茫的,或者想系統深入提升以及困於瓶頸的朋友,在網上部落格論壇等地方少花些時間找資料,把有限的時間,真正花在學習上,所以我在這免費分享一些架構資料及給大家。希望在這些資料中都有你需要的內容。

