Android的多種數(shù)據(jù)存儲方法
Android為你提供了若干選項用于存儲應(yīng)用程序數(shù)據(jù)。選擇何種方案時情況而定。比如,數(shù)據(jù)僅為你的應(yīng)用所使用,或是可是為其他應(yīng)用(以及用戶)所共享。又比如,你的數(shù)據(jù)需要多少空間。
本文引用地址:http://cafeforensic.com/article/201610/306012.htm數(shù)據(jù)存儲有以下幾個選擇:
Data_Storage#.E4.BD.BF.E7.94.A8.E5.85.B1.E4.BA.AB.E7.9A.84.E9.85.8D.E7.BD.AE_-_Using_Shared_Preferences|Shared Preferences|公共配置-Shared Preferences
通過鍵值對的方式存儲私有的原始數(shù)據(jù)。
Data_Storage#.E4.BD.BF.E7.94.A8.E5.86.85.E9.83.A8.E5.AD.98.E5.82.A8_-_Using_the_Internal_Storage|Internal Storage|內(nèi)部存儲-Internal Storage
在存儲器上存儲私有的數(shù)據(jù)。
Data_Storage#.E4.BD.BF.E7.94.A8.E5.86.85.E9.83.A8.E5.AD.98.E5.82.A8_-_Using_the_Internal_Storage|External Storage | 外部存儲 - External Storage
在外部存儲器上存儲公開的數(shù)據(jù)。
Data_Storage#.E4.BD.BF.E7.94.A8.E6.95.B0.E6.8D.AE.E5.BA.93_-_Using_Databases|SQLite Database | SQLite數(shù)據(jù)庫 - SQLite Database
在私有的數(shù)據(jù)庫中存儲結(jié)構(gòu)化的數(shù)據(jù)。
Data_Storage#.E4.BD.BF.E7.94.A8.E7.BD.91.E7.BB.9C.E8.BF.9E.E6.8E.A5_-_Using_a_Network_Connection|Network Connection | 網(wǎng)絡(luò)連接 - Network Connection
使用你的網(wǎng)絡(luò)服務(wù)器存儲數(shù)據(jù)。
Android提供了暴露私有數(shù)據(jù)給其他應(yīng)用的方法——使用一個內(nèi)容提供器(content provider)。內(nèi)容提供器是一個可選的組件,為你的應(yīng)用程序數(shù)據(jù)提供讀/寫權(quán)限,并受制于你給定的限制。關(guān)于使用內(nèi)容提供器的更多細節(jié),請查看Content Providers的文檔。
使用共享的配置 - Using Shared Preferences
SharedPreferences類提供了一個通用的框架,用于保存和檢索以持久化的鍵值對形式存儲的原始數(shù)據(jù)類型。你可以使用SharedPreferences保存任意類型的原始數(shù)據(jù):布爾(boolean),浮點,(float),整型(int),長整型(long)和字符串(string)。這些數(shù)據(jù)將會存放在用戶會話中(即使你的應(yīng)用程序已經(jīng)退出)。
* 用戶配置*
共享的配置并非一定要保存用戶配置,例如用戶選擇和哪個鈴聲。如果你有興趣為你的應(yīng)用創(chuàng)建用戶配置,請參考PreferenceActivity。它提供了一個Activity的框架,可以用來創(chuàng)建持久化的用戶配置(使用共享的配置)。
在應(yīng)用程序中取得SharedPreferences對象,使用以下兩種方法之一:
* int) getSharedPreferences() getPreferences()](http://developer.android.com/reference/android/content/Context.html#getSharedPreferencesjava.lang.String,)( - 當(dāng)你僅需要一個配置文件。由于這是你的Activity的唯一一個配置文件,所以不必提供名稱。
向SharedPreferences寫入值的步驟:
1、調(diào)用edit(),取得一個SharedPreferences.Editor。
2、使用形如boolean) putBoolean() putString()](http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#putStringjava.lang.String,)這樣的方法添加值。(
3、使用commit()提交新值。
從SharedPreferences讀取值,使用它的方法,例如boolean) getBoolean() getString()](http://developer.android.com/reference/android/content/SharedPreferences.html#getStringjava.lang.String,)即可。(
這是一個例子,在一個計算器中使用無聲的按鍵保存一個配置:
class extends { static String PREFS_NAME ; protected (){ .onCreate); . // Restore preferences color:#660>(PREFS_NAME0boolean silent settings(, ); setSilent); @Override void onStopsuper(); // All objects are from android.context.Context color:#660>(PREFS_NAME0SharedPreferencesEditor editor settings(); editor(, mSilentMode// Commit the edits! editor(); }
使用內(nèi)部存儲 - Using the Internal Storage
你可以直接將文件保存在設(shè)備上的內(nèi)部存儲中。缺省情況下,存放于內(nèi)部存儲的文件為你的應(yīng)用程序所私有,其他應(yīng)用程序不能夠訪問它們(其他用戶亦然)。當(dāng)用戶卸載你的應(yīng)用,這些文件也被刪除。
在內(nèi)部存儲中創(chuàng)建并寫入一個私有文件:
1、調(diào)用openFileOutput(),傳入文件名和操作模式。方法返回一個FileOutputStream對象。
2、使用write()寫文件。
3、使用close()關(guān)閉文件流。
例如:
color:#080>hello_fileString color:#080>hello world!FileOutputStream fos openFileOutput, .MODE_PRIVATE.writestring());fos();
MODE_PRIVATE創(chuàng)建文件(或以同名文件替換),并為你的應(yīng)用所私有。其他可用的模式有:MODE_APPEND, MODE_WORLD_READABLE, 和MODE_WORLD_WRITEABLE。
從內(nèi)部存儲中讀一個文件:
1、調(diào)用openFileInput(),并傳遞需要讀取的文件的名稱。這個方法返回一個FileInputStream。
2、使用read()從文件中讀取數(shù)據(jù)。
3、使用close()關(guān)閉文件流。
提示:如果你想在編譯時往你的應(yīng)用中存入一個靜態(tài)文件,就得把文件保存到項目的res/raw目錄下。你可以調(diào)用openRawResource()并傳遞資源的ID(R.raw.)來打開它。這個方法返回一個InputStream,你可以使用它讀取文件,但不能夠?qū)懭脒@個原始文件。
保存緩存文件
如果你想要緩存一些數(shù)據(jù),而不是保存它們,你應(yīng)該調(diào)用getCacheDir()打開一個File對象,它表示你的應(yīng)用應(yīng)當(dāng)保存臨時緩存文件的內(nèi)部目錄。
其他有用的方法
getFilesDir() 取得內(nèi)部文件在文件系統(tǒng)中保存位置的絕對路徑。
getDir() 創(chuàng)建(或者打開已存在的)內(nèi)部存儲空間所在的目錄。
deleteFile() 刪除內(nèi)部存儲的一個文件。
fileList() 返回當(dāng)前由你的應(yīng)用保存的文件的列表。
使用外部存儲 - Using the External Storage
所有兼容Android的設(shè)備都支持一個可共享的“外部存儲(external storage)”,可用來保存文件。這可以使一個可移動的存儲設(shè)備(比如SD卡)或者一個內(nèi)部的(不可移動的)存儲。保存在外部存儲的文件是可讀的。并且當(dāng)用于傳輸數(shù)據(jù)的USB大容量存儲選項啟用時,用戶能夠在計算機上修改它們。
注意:* 如果用戶掛載外部存儲到計算機上,或者移除媒體,外部文件將會消失不見。并且對于這些保存在外部存儲的文件,沒有強制的安全措施。所有的應(yīng)用都可以讀/寫這些文件。用戶也能夠刪除它們。
檢測媒體可用性
在你對外部存儲做任何事情之前,你總是應(yīng)當(dāng)調(diào)用getExternalStorageState()以檢測媒體是否可用。媒體可能被計算機掛載,可能丟失,可能只讀,或者處于某些其他狀態(tài)。比如,這是示例代碼:
color:#008>falseboolean mExternalStorageWriteable ;color:#606>Environment();(.MEDIA_MOUNTED(state{ color:#660>color:#008>true} if Environment.equals)) // We can only read the media mExternalStorageAvailable ; mExternalStorageWriteable ;else // Something else is wrong. It may be one of many other states, but all we need color:#660>color:#008>false}
這個例子檢測了外部存儲是否可讀或可寫。getExternalStorageState()方法返回你想要檢測的其他狀態(tài)。比如,媒體是否被共享(已連接到一臺計算機),是否完全丟失,是否被移除等等。當(dāng)你的應(yīng)用需要訪問媒體時,你可以依據(jù)這些以更詳細的信息通知用戶。
訪問位于外部存儲的文件
如果你正在使用API Level 8或者更高版本,使用getExternalFilesDir()打開一個文件對象,它表示你的應(yīng)用應(yīng)當(dāng)保存文件所在的外部存儲目錄。這個方法需要一個類型參數(shù),指定你需要的子目錄類型,比如DIRECTORY_MUSIC或者DIRECTORY_RINGTONES(傳遞null表示你的應(yīng)用程序的目錄所在的根目錄)。如有必要,這個方法將會創(chuàng)建一個目錄。通過指定目錄的類型,你確信Android的媒體掃描器會將系統(tǒng)中的文件正確分類(例如,鈴聲將被歸類為鈴聲而不是音樂)。如果用戶卸載了你的應(yīng)用,這個目錄以及它的內(nèi)容將會被刪除。
如果你正在使用API Level 7或者更低版本,使用getExternalStorageDirectory()打開一個文件對象,它表示外部存儲的根目錄。接下來,你應(yīng)當(dāng)寫入你的數(shù)據(jù)在一下目錄:
/Android/data//files/
com.example.android.app。如果用戶的設(shè)備正在運行API Level 8或者更高版本,且用戶卸載了你的應(yīng)用,這個目錄和它的內(nèi)容將會被刪除。
保存應(yīng)當(dāng)共享的文件
在媒體掃描器下隱藏你的文件
在你的外部文件目錄中放置包括一個空的文件,命名為.nomedia(注意文件名前綴的點)。這會阻止Android的媒體掃描器讀取你的媒體文件,并并在類似Gallery或者Music這樣的應(yīng)用中包括它們。
如果你想要保存與你的應(yīng)用沒有關(guān)聯(lián)的文件,并且這些文件不應(yīng)在應(yīng)用卸載時被刪除,把他們保存在外部存儲的一個公共目錄上即可。這些目錄位于外部存儲的根目錄下,比如Music/, Pictures/, Ringtones/,以及其它目錄。
在API Level 8或者更高版本,調(diào)用getExternalStoragePublicDirectory(),傳遞你需要的公共目錄的類型,比如DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES或者其它。如有必要,這個方法會創(chuàng)建新目錄。
如果你正在使用API Level 7或者更低版本,調(diào)用getExternalStorageDirectory()打開一個File,它表示外部存儲的根目錄。接著保存你的共享文件在以下文件夾之一:
Music/ - 媒體掃描器把所有在此發(fā)現(xiàn)的媒體歸類為用戶的音樂。
Podcasts/ - 媒體掃描器把所有在此發(fā)現(xiàn)的媒體歸類為播客。
Ringtones/ - 媒體掃描器把所有在此發(fā)現(xiàn)的媒體歸類為鈴聲。
Alarms/ - 媒體掃描器把所有在此發(fā)現(xiàn)的媒體歸類為鬧鈴。
Notifications/ - 媒體掃描器把所有在此發(fā)現(xiàn)的媒體歸類為提示音。
Pictures/ - 所有照片(相機拍攝的除外)。
Movies/ - 所有影片(攝像機拍攝的除外)。
Download/ - 各類下載。
保存緩存文件
如果你正在使用API Level 8或者更高版本,調(diào)用getExternalCacheDir()打開一個File,它表示你的應(yīng)用應(yīng)當(dāng)保存文件所在的外部存儲目錄。如果用戶卸載了你的應(yīng)用,這些文件會被自動刪除。然而,在你的應(yīng)用的生命周期中,你應(yīng)當(dāng)管理這些緩存文件以及刪除其中過期的部分以保證文件空間。
如果你正在使用API Level 7或者更低版本,使用getExternalStorageDirectory()打開一個File,它表示外部存儲的根目錄。接下來,你應(yīng)當(dāng)寫入你的數(shù)據(jù)在一下目錄:
/Android/data//files/
com.example.android.app。
使用數(shù)據(jù)庫 - Using Databases
Android提供了對SQLite數(shù)據(jù)庫的完整支持。你創(chuàng)建的任何數(shù)據(jù)庫都能被應(yīng)用程序中的任意類通過數(shù)據(jù)庫名訪問。但是不能夠在應(yīng)用程序以外訪問。
推薦的創(chuàng)建新的SQLite數(shù)據(jù)庫的方法是,在你執(zhí)行SQLite命令在數(shù)據(jù)庫中創(chuàng)建表的時候,創(chuàng)建一個SQLiteOpenHelper的子類,并重寫onCreate()方法。例如:
class extends { static int DATABASE_VERSION ; static String DICTIONARY_TABLE_NAME ; static String DICTIONARY_TABLE_CREATE + DICTIONARY_TABLE_NAME ( + + KEY_DEFINITION TEXT);DictionaryOpenHelperContext context{ (context, , DATABASE_VERSION} public () .execSQL); }
接著,你可以使用構(gòu)造方法取得你實現(xiàn)的SQLiteOpenHelper的一個實例。分別使用getWritableDatabase()和getReadableDatabase()讀寫數(shù)據(jù)庫。兩者都會返回一個SQLiteDatabase對象,代表那個數(shù)據(jù)庫,并提供操作SQLite的方法。
Android沒有在標(biāo)準(zhǔn)SQLite概念之外加以任何限制。我們建議包含一個自增值的主鍵字段,能夠作為一個唯一的ID,以便快速定位一條記錄。這對私有數(shù)據(jù)來說不是必須的。但如果你實現(xiàn)了一個content provider,就必須包含一個唯一的ID,它使用BaseColumns._ID常量。
你可以使用SQLiteDatabase.query()方法執(zhí)行SQLite查詢,這個方法接受各種查詢參數(shù),例如待查詢的表、投影、選擇、列、組,或者其他。對于復(fù)雜查詢,比如一些需要用到列的別名的,你應(yīng)當(dāng)使用SQLiteQueryBuilder,它能提供一些合適的方法以創(chuàng)建查詢。
每一個SQLite查詢都會返回一個Cursor對象,指向查詢得到的所有行。Cursor對象總是你用來取得數(shù)據(jù)庫查詢或者讀取行或列的結(jié)果的途徑。
關(guān)于示例應(yīng)用中演示如何在Android中使用SQLite數(shù)據(jù)庫,見Node Pad和Searchable Dictionary這兩個應(yīng)用。
數(shù)據(jù)庫調(diào)試
Android SDK包含了一個sqlite3的數(shù)據(jù)庫工具,允許你瀏覽表內(nèi)容,運行SQL命令,以及執(zhí)行其他SQLite數(shù)據(jù)庫中有用的功能。想要了解如何運行這個工具,請查看Examining sqlite3 databases from a remote shell這個例子。
使用網(wǎng)絡(luò)連接 - Using a Network Connection
你可以使用網(wǎng)絡(luò)連接(當(dāng)可用時)通過基于web的服務(wù)存儲或取得數(shù)據(jù)。需要執(zhí)行網(wǎng)絡(luò)操作時,使用以下包中的類:
java.net.*
android.net.*
評論