源碼運行請見文章最後。
本文主要介紹Android中的5種資料存放區方式。
資料存放區在開發中是使用最頻繁的,在這裡主要介紹Android平台中實現資料存放區的5種方式,分別是:
1 使用SharedPreferences儲存資料
2 檔案儲存體資料
3 SQLite資料庫儲存資料
4 使用ContentProvider儲存資料
5 網路儲存資料
第一種: 使用SharedPreferences儲存資料
SharedPreferences是Android平台上一個輕量級的儲存類,主要是儲存一些常用的配置比如視窗狀態,一般在Activity中重載視窗狀態onSaveInstanceState儲存一般使用SharedPreferences完成,它提供了Android平台常規的Long長整形、Int整形、String字串型的儲存。
SharedPreferences類似過去Windows系統上的ini設定檔,但是它分為多種許可權:
●MODE_PRIVATE 私人、新內容覆蓋原內容
●MODE_APPEND 新內容追加到原內容
●MODE_WORLD_READABLE 全域讀、允許其他應用程式讀取
●MODE_WORLD_WRITEABLE 全域寫、允許其他應用程式寫入,會覆蓋原資料
最終是以xml方式來儲存,整體效率來看不是特別的高,對於常規的輕量級而言比SQLite要好不少,如果真的儲存量不大可以考慮自己定義檔案格式。xml 處理時Dalvik會通過內建底層的本地XML Parser解析,比如XMLpull方式,這樣對於記憶體資源佔用比較好。
它的本質是基於XML檔案儲存體key-value索引值對資料,通常用來儲存一些簡單的配置資訊。
其儲存位置在/data/data/<包名>/shared_prefs目錄下。
SharedPreferences對象本身只能擷取資料而不支援儲存和修改,儲存修改是通過Editor對象實現。
實現SharedPreferences儲存的步驟如下:
一、根據Context擷取SharedPreferences對象
二、利用edit()方法擷取Editor對象。
三、通過EditorObject Storage Servicekey-value索引值對資料。
四、通過commit()或者apply()方法提交資料。
下面是範例程式碼:
[java]
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//擷取SharedPreferences對象
Context ctx = MainActivity.this;
SharedPreferences sp = ctx.getSharedPreferences("SP", MODE_PRIVATE);
//存入資料
Editor editor = sp.edit();
editor.putString("STRING_KEY", "string");
editor.putInt("INT_KEY", 0);
editor.putBoolean("BOOLEAN_KEY", true);
editor.commit();
//返回STRING_KEY的值
Log.d("SP", sp.getString("STRING_KEY", "none"));
//如果NOT_EXIST不存在,則傳回值為"none"
Log.d("SP", sp.getString("NOT_EXIST", "none"));
}
}
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//擷取SharedPreferences對象
Context ctx = MainActivity.this;
SharedPreferences sp = ctx.getSharedPreferences("SP", MODE_PRIVATE);
//存入資料
Editor editor = sp.edit();
editor.putString("STRING_KEY", "string");
editor.putInt("INT_KEY", 0);
editor.putBoolean("BOOLEAN_KEY", true);
editor.commit();
//返回STRING_KEY的值
Log.d("SP", sp.getString("STRING_KEY", "none"));
//如果NOT_EXIST不存在,則傳回值為"none"
Log.d("SP", sp.getString("NOT_EXIST", "none"));
}
}
這段代碼執行過後,即在/data/data/com.test/shared_prefs目錄下產生了一個SP.xml檔案,一個應用可以建立多個這樣的xml檔案。
SharedPreferences對象與SQLite資料庫相比,免去了建立資料庫,建立表,寫SQL語句等諸多操作,相對而言更加方便,簡潔。但是SharedPreferences也有其自身缺陷,比如其職能儲存boolean,int,float,long和String五種簡單的資料類型,比如其無法進行條件查詢等。所以不論SharedPreferences的資料存放區操作是如何簡單,它也只能是儲存方式的一種補充,而無法完全替代如SQLite資料庫這樣的其他資料存放區方式。
第二種:檔案儲存體資料
關於檔案儲存體,Activity提供了openFileOutput()方法可以用於把資料輸出到檔案中,具體的實現過程與在J2SE環境中儲存資料到檔案中是一樣的。
檔案可用來存放大量資料,如文本、圖片、音頻等。
預設位置:/data/data/<包>/files/***.***。
[java]
public void save() {
try {
FileOutputStream outStream=this.openFileOutput("a.txt",Context.MODE_WORLD_READABLE);
outStream.write(text.getText().toString().getBytes());
outStream.close();
Toast.makeText(MyActivity.this,"Saved",Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
return;
}
catch (IOException e){
return ;
}
}
public void save() {
try {
FileOutputStream outStream=this.openFileOutput("a.txt",Context.MODE_WORLD_READABLE);
outStream.write(text.getText().toString().getBytes());
outStream.close();
Toast.makeText(MyActivity.this,"Saved",Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
return;
}
catch (IOException e){
return ;
}
}
openFileOutput()方法的第一參數用於指定檔案名稱,不能包含路徑分隔字元“/” ,如果檔案不存在,Android 會自動建立它。
建立的檔案儲存在/data/data/<packagename>/files目錄,如: /data/data/cn.itcast.action/files/itcast.txt ,通過點擊Eclipse菜單“Window”-“ShowView”-“Other”,在交談視窗中展開android檔案夾,選擇下面的File Explorer視圖,然後在File Explorer視圖中展開/data/data/<package name>/files目錄就可以看到該檔案。
openFileOutput()方法的第二參數用於指定操作模式,有四種模式,分別為:
Context.MODE_PRIVATE= 0
Context.MODE_APPEND= 32768
Context.MODE_WORLD_READABLE= 1
Context.MODE_WORLD_WRITEABLE= 2
Context.MODE_PRIVATE:為預設操作模式,代表該檔案是私人資料,只能被應用本身訪問,在該模式下,寫入的內容會覆蓋原檔案的內容,如果想把新寫入的內容追加到原檔案中。可以使用Context.MODE_APPEND
Context.MODE_APPEND:模式會檢查檔案是否存在,存在就往檔案追加內容,否則就建立新檔案。
Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用來控制其他應用是否有許可權讀寫該檔案。
MODE_WORLD_READABLE:表示當前檔案可以被其他應用讀取;
MODE_WORLD_WRITEABLE:表示當前檔案可以被其他應用寫入。
如果希望檔案被其他應用讀和寫,可以傳入: openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE+ Context.MODE_WORLD_WRITEABLE); android有一套自己的安全模型,當應用程式(.apk)在安裝時系統就會分配給他一個userid,當該應用要去訪問其他資源比如檔案的時候,就需要userid匹配。預設情況下,任何應用建立的檔案,sharedpreferences,資料庫都應該是私人的(位於/data/data/<package name>/files),其他程式無法訪問。
除非在建立時指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE,只有這樣其他程式才能正確訪問。
讀取檔案樣本:
[java]
public void load()
{
try {
FileInputStream inStream=this.openFileInput("a.txt");
ByteArrayOutputStream stream=new ByteArrayOutputStream();
byte[] buffer=new byte[1024];
int length=-1;
while((length=inStream.read(buffer))!=-1) {
stream.write(buffer,0,length);
}
stream.close();
inStream.close();
text.setText(stream.toString());
Toast.makeText(MyActivity.this,"Loaded",Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e){
return ;
}
}
public void load()
{
try {
FileInputStream inStream=this.openFileInput("a.txt");
ByteArrayOutputStream stream=new ByteArrayOutputStream();
byte[] buffer=new byte[1024];
int length=-1;
while((length=inStream.read(buffer))!=-1) {
stream.write(buffer,0,length);
}
stream.close();
inStream.close();
text.setText(stream.toString());
Toast.makeText(MyActivity.this,"Loaded",Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e){
return ;
}
}
對於私人檔案只能被建立該檔案的應用訪問,如果希望檔案能被其他應用讀和寫,可以在建立檔案時,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE許可權。
Activity還提供了getCacheDir()和getFilesDir()方法:getCacheDir()方法用於擷取/data/data/<package name>/cache目錄 getFilesDir()方法用於擷取/data/data/<packagename>/files目錄。
把檔案存入SDCard:
使用Activity的openFileOutput()方法儲存檔案,檔案是存放在手機空間上,一般手機的儲存空間不是很大,存放些小檔案還行,如果要存放像視頻這樣的大檔案,是不可行的。對於像視頻這樣的大檔案,我們可以把它存放在SDCard。
SDCard是幹什麼的?你可以把它看作是移動硬碟或隨身碟。在模擬器中使用SDCard,你需要先建立一張SDCard卡(當然不是真的SDCard,只是鏡像檔案)。
建立SDCard可以在Eclipse建立模擬器時隨同建立,也可以使用DOS命令進行建立,如下:在Dos視窗中進入android SDK安裝路徑的tools目錄,輸入以下命令建立一張容量為2G的SDCard,檔案尾碼可以隨便取,建議使用.img: mksdcard 2048M D:\AndroidTool\sdcard.img 在程式中訪問SDCard,你需要申請訪問SDCard的許可權。
在AndroidManifest.xml中加入訪問SDCard的許可權如下:
[html]
<!-- 在SDCard中建立與刪除檔案許可權 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard寫入資料許可權 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 在SDCard中建立與刪除檔案許可權 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard寫入資料許可權 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
[java]
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();//擷取SDCard目錄
File saveFile = new File(sdCardDir, “a.txt”);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("test".getBytes());
outStream.close();
}
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir = Environment.getExternalStorageDirectory();//擷取SDCard目錄
File saveFile = new File(sdCardDir, “a.txt”);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("test".getBytes());
outStream.close();
}
Environment.getExternalStorageState()方法用於擷取SDCard的狀態,如果手機裝有SDCard,並且可以進行讀寫,那麼方法返回的狀態等於Environment.MEDIA_MOUNTED。
Environment.getExternalStorageDirectory()方法用於擷取SDCard的目錄,當然要擷取SDCard的目錄,你也可以這樣寫:
[java]
File sdCardDir = new File("/sdcard"); //擷取SDCard目錄
File saveFile = new File(sdCardDir, "itcast.txt");
//上面兩句代碼可以合成一句:
File saveFile = new File("/sdcard/a.txt");
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("test".getBytes());
outStream.close();
File sdCardDir = new File("/sdcard"); //擷取SDCard目錄
File saveFile = new File(sdCardDir, "itcast.txt");
//上面兩句代碼可以合成一句:
File saveFile = new File("/sdcard/a.txt");
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write("test".getBytes());
outStream.close();
第三種: SQLite資料庫儲存資料
SQLite是輕量級嵌入式資料庫引擎,它支援 SQL 語言,並且只利用很少的記憶體就有很好的效能。此外它還是開源的,任何人都可以使用它。許多開源項目((Mozilla, PHP, Python)都使用了 SQLite.SQLite 由以下幾個組件組成:SQL 編譯器、核心、後端以及附件。SQLite 通過利用虛擬機器和虛擬資料庫引擎(VDBE),使調試、修改和擴充 SQLite 的核心變得更加方便。
特點:
面向資源有限的裝置,
沒有伺服器處理序,
所有資料存放在同一檔案中跨平台,
可自由複製。