Android本地儲存的幾種方式

_小馬快跑_發表於2018-01-23

Android提供了多種選擇來儲存永久性的資料,根據不同的需求來使用不同的儲存方式,一般情況下,儲存資料的方式有下面幾種:

  • SharedPreferences
  • 內部儲存
  • 外部儲存
  • SQLite
  • 網路連線

下面主要來看一下前四種資料儲存方式。

SharedPreferences

SharedPreferences(以下簡稱SP)以鍵值對形式進行儲存,資料以xml形式儲存在/data/data/專案包名/shared_prefs/xml.xml中。一般來說,SP只能儲存基本型別的資料,如:布林型別、浮點型、整形及字串,預設情況下,SP儲存的檔案是應用的私有檔案,其他應用(和使用者)不能訪問這些檔案,SP的使用方式及原始碼解析詳見: http://blog.csdn.net/u013700502/article/details/53635499

SP不支援多程式之間通訊,多程式之間使用可能會導致資料異常,替代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/下可以看到已經成功建立了相應檔案並且把資料寫進去了:

S80114-23015717.jpg

其他方法(都在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

相關文章