Android實現數據存儲技術集錦

源碼運行效果圖請見文章最後。

本文主要介紹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對象。   

         三、通過Editor對象存儲key-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是幹什麼的?你可以把它看作是移動硬盤或U盤。在模擬器中使用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 的內核變得更加方便。

 

         特點:

         面向資源有限的設備,

         沒有服務器進程,

         所有數據存放在同一文件中跨平臺,

         可自由復制。

 

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *