Android本地存儲的幾種方式


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();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
我們在/data/data/項目包名/files/下可以看到已經成功創建了相應文件並且把數據寫進去了:

 

其他方法(都在Context類中):

getFilesDir() 獲取在其中存儲內部文件的文件系統目錄的絕對路徑。
返回路徑為:/data/data/com.xxx.xxx/files
getDir()
在您的內部存儲空間內創建(或打開現有的)目錄。如:
getDir("mq", Context.MODE_PRIVATE).getAbsolutePath()
1
返回結果: /data/data/com.xxx.xxx/app_mq, 我們看到系統自動給我們的文件名前加了”app_”

deleteFile()
刪除保存在內部存儲的文件。如:
deleteFile("mq")
1
刪除*/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>
1
2
3
4
5
注:當用戶卸載您的應用時,此目錄及其內容將被刪除。此外,系統媒體掃描程序不會讀取這些目錄中的文件,因此不能從 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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM