標籤:
轉載:http://mp.weixin.qq.com/s?__biz=MzIzMjE1Njg4Mw==&mid=2650117688&idx=1&sn=d6c73f9f04d02ede7a741b45e801d74e#rd
本篇文章會協助大家快速瞭解Android中各種資料存放區機制的應用情境以及基本使用方法,力求在頭腦中建立一個“目錄”。有了這個目錄,具體使用細節在實際應用時再查詢文檔即可得到。
0. 概述
Android為我們提供了以下儲存機制:
Shared Preferences: 以鍵-值對方式儲存應用私人的原始類型資料。
Internal Storage(內部儲存): 儲存應用私人資料於裝置本身的儲存空間中
External Storage(外部儲存): 將公用資料存放區於外部儲存(如SD卡)中
SQLite Databases(SQLite資料庫): 將結構化資料存放區於私人資料庫中
Network Connection: 將資料存放區在你的網路伺服器中
在以上幾種資料存放區方式中,我們可以根據實際需求進行靈活選擇。比如,“資料是本應用私人的還是與其他應用共用”、“要儲存的資料大概需要多少儲存空間”等都是我們在選擇具體的資料存放區機制時所要考慮的問題。下面我們來一起看一下這幾種儲存機制的應用情境和基本使用方法。
1. 使用Shared Preferences
這種儲存方式用於儲存原始類型資料,包括boolean、int、long、float、double、String等。具體的儲存方式是鍵-值對,若我們不主動刪除,這些資料會一直存在。
根據以上介紹,我們很容易得出Shared Preferences適合儲存的資料有:
要使用Shared Preferences,我們首先要擷取一個SharedPreference對象,要擷取這個對象有兩種方法:
在通過以上兩種方式之一擷取到一個SharedPreferences對象後,我們就可以開始向其中寫如使用者資料了,具體步驟如下:
只需三步,我們就成功地把使用者資料存起來啦。那麼當我們想再此擷取已儲存的資料時,該怎麼做呢?很簡單:只需要得到一個SharedPreferences後調用 getBoolean(),getBoolean()等方法即可。
我們來看一下來自Android Developer的範例程式碼:
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
//從preferences檔案中讀取之前我們儲存的資料
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
@Override
protected void onStop(){
super.onStop();
// 儲存使用者資料
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// 提交後對使用者資料的儲存才生效
editor.commit();
}
}
2. 使用內部儲存
使用這種方式會把資料存到應用私人的儲存空間中,其他應用無權訪問這個儲存空間,並且當使用者卸載你的應用時,這些資料也會被刪除掉。由此我們可以知道當我們要儲存的資料只用於本應用時,並且希望它同本應用“同生共死”時,就可以使用內部儲存。
要建立一個應用私人檔案用於資料儲存也只需要三步:
樣本如下:
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
上面方法中的MODE_PRIVATE 參數的意思就是這個資料檔案是本應用私人的,其他應用不可以訪問。
要從內部儲存的檔案中讀取資料也很簡單,只需三步:
有些時候我們想要儲存一些臨時資料在應用的私人儲存空間中,這時候我們可以通過 getCacheDir()方法得到應用用於儲存臨時快取檔案的內部目錄。儲存在這個目錄下的檔案有個特點:當內部儲存空間不足時,系統會自動刪除一些這個檔案夾下的檔案。當然,剛靠譜的方式是我們自己維護這個檔案夾下的檔案。同樣,這個檔案夾下的檔案在應用被卸載時候也會被刪除。
關於使用內部儲存更詳細的介紹請參考文末”參考資料“部分給出的連結。
3. 使用外部儲存
Android中的外部儲存通常指SD卡,儲存於外部儲存的檔案通常對於各個應用來說是共用的。顯然,當我們希望儲存的資料被系統中的各個應用共用時,就可以考慮使用外部儲存;另一方面,由於手機的內部儲存普遍較外部儲存小,我們也應該把一些比較大的資料檔案放於外部儲存中。儲存於外部儲存中的資料檔案不會隨著應用的卸載而被刪除。
要讀寫外部儲存中的檔案,我們首先需要在AndroidManifest.xml檔案中聲明如下許可權:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
這樣既可以了嗎?顯然不行,我們在使用外部儲存前首先要確保使用者的手機中存在可用的外部儲存(萬一使用者的手機裡壓根沒有SD卡呢...)。實現這個很簡單,請看官方給出的範例程式碼:
/* 檢查是否可以讀寫外部儲存 */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* 檢查是否只能夠讀而不能寫外部儲存 */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
對於一些公用的音樂、圖片或是鈴聲檔案,我們可以將它們分別儲存於外部儲存的 Music/, Pictures/,Ringtones/檔案夾中。要得到代表上述公用檔案夾的File對象,只需調用getExternalStoragePublicDirectory()方法,並傳入一個參數指明我們具體想訪問哪個檔案夾(DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES等)。
比如下面的方法在公用圖片目錄中建立了一個用於儲存新相簿的檔案夾:
public File getAlbumStorageDir(String albumName) {
// Get the directory for the user‘s public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
那麼當我們僅僅是因為手機內部儲存不足而把資料存於外部儲存,有沒有辦法讓這些資料是本應用私人的呢?答案是肯定的。我們只需調用getExternalFilesDir()方法來擷取一個外部儲存中的私人儲存目錄。位於這個目錄中的資料檔案會隨著應用的卸載而被刪除,畢竟它們只對該應用本身有意義。
從Android 4.4(API 19)開始,讀寫這個位於外部儲存中的應用私人目錄無需加上許可權聲明。所以我們可以在AndroidManifest.xml中添加maxSdkVersion 屬性來說明這一許可權只在Android 4.4之前才需要。
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest>
同內部儲存一樣,外部儲存中也有個專門用來儲存臨時檔案的快取檔案夾。要擷取代表本應用的快取檔案夾的File對象,只需調用getExternalCacheDir()方法,當使用者卸載引用時,這些檔案也會被自動刪除。
4. 使用SQLite資料庫
前面我們提到過,SQLite資料庫用來儲存結構化資料,所謂機構化資料就是有著固定結構的資料。比如成績表、工資表等等就是天然的適合用資料庫儲存的結構化資料。
Android推薦的訪問SQLite資料庫的方式是建立一個SQLiteOpenHelper的子類並重寫 onCreate()方法,在這個方法中執行建立資料庫表的SQLite命令,比如以下代碼:
public class DictionaryOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DICTIONARY_TABLE_NAME = "dictionary";
private static final String DICTIONARY_TABLE_CREATE =
"CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
KEY_WORD + " TEXT, " +
KEY_DEFINITION + " TEXT);";
DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DICTIONARY_TABLE_CREATE);
}
}
然後我們就可以擷取以上 SQLiteOpenHelper子類的執行個體開始對資料庫進行操作了。我們可以分別調用 getReadableDatabase()和getWritableDatabase()方法來對資料庫進行讀操作和寫操作。這倆方法都會返回一個 SQLiteDatabase 對象,這個對象提供了查改增刪等資料庫常規操作方法。
要對SQLite資料庫執行查詢操作,可以調用 SQLiteDatabase query() 方法。對於複雜查詢操作,則使用SQLiteQueryBuilder是個更好的選擇。
每個SQLite查詢操作都會返回一個指向了“符合查詢條件的所有行"的Cursor對象。關於Android中使用SQLite更加詳細的介紹,大家可以參考文末給出的連結。
5. 參考資料
Android Developer: https://developer.android.com/guide/topics/data/data-storage.html(牆內使用者請看這裡:http://hukai.me/android-training-course-in-chinese/basics/data-storage/index.html)
Android中SQLite的使用:http://www.cnblogs.com/Excellent/archive/2011/11/19/2254888.html
67.Android中的資料存放區總結