《Android和PHP開發最佳實踐》一2.6 Android資料儲存

華章計算機發表於2017-08-01

2.6 Android資料儲存

前面剛介紹過上下文物件的使用,其最重要的功能之一,就是用於儲存應用執行期間產生的中間資料。接下來,我們來討論Android應用中持久化型別資料的儲存方案。對於移動網際網路應用來說,我們經常把核心資料儲存在服務端,也就是我們常說的“雲端”,但是在實際專案中也會經常使用到Android系統內部的資料儲存方案,接下來讓我們認識一下幾種最常用的資料儲存方案。

2.6.1 應用配置(Shared Preferences)

在Android系統中,系統配置(Shared Preferences)是一種輕量級的資料儲存策略,只能用於儲存key-value格式的資料(類似於ini格式),因此這個特點也決定了我們不可能在其中儲存其他各種複雜格式的資料。由於系統配置使用起來比較簡單方便,所以我們經常用它來儲存一些類似於應用配置形式的資訊。程式碼清單2-14就是一個簡單的例子。
程式碼清單 2-14

...
settings = getPreferences(Context.MODE_PRIVATE);
if (settings.getString("username", null) == null) {
       SharedPreferences.Editor editor = settings.edit();
       editor.putString("username", "james");
       editor.commit();
}
...

以上程式碼的邏輯很簡單:先檢查是否存在“username”的值,若不存在則儲存“james”字串為“username”。這裡我們重點分析兩點:首先是關於Context.MODE_PRIVATE,MODE_PRIVATE代表此時Shared Preferences儲存的資料是僅供應用內部訪問的,除此之外,Android系統中還提供MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE兩種模式,分別用於表示資料是否允許其他應用來讀或者寫;另外還需要注意的一點是,我們在運算元據的時候必須使用SharedPreferences.Editor介面來編輯和儲存資料,最後還必須呼叫commit方法進行提交,否則資料將不會被儲存。
另外,系統配置資訊會被儲存在“/data/data”下對應的應用包名下的shared_prefs目錄裡,一般是以XML檔案格式來儲存的。在Eclipse中,我們可以使用DDMS工具(本章的2.10.3節會介紹)開啟對應的目錄進行檢視。

2.6.2 本地檔案(Files)

將資料儲存成為檔案應該是所有系統都會提供的一種比較簡單的資料儲存方法,我們已經知道Android系統是基於Linux系統來開發的,而Linux系統就是一個檔案系統,很多的資料都是以檔案形式存在的。與系統配置不同,檔案可儲存的格式是沒有限制的,所以使用範圍自然也比系統配置廣得多,除了可用於各種型別檔案的讀寫,我們還經常用於儲存一些二進位制的快取資料,比如圖片等。
在Android中,我們一般使用openFileOutput方法來開啟一個檔案,此方法會返回一個FileInputStream物件,然後我們就可以選擇使用合適的方法來運算元據。比如,對於cfg或者ini型別的檔案來說,我們可以使用Properties的load方法來直接載入;對於其他普通的檔案,我們則可以使用InputStreamReader和BufferedReader來讀取。程式碼清單2-15就是一個典型的在Android系統中讀取檔案內容的例子。
程式碼清單 2-15

...
public String getFileContent (String filePath) {
    StringBuffer sb = new StringBuffer();
    FileInputStream stream = null;
    try {
        stream = this.openFileInput(filePath);
        BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
    } catch (...) {
        ...
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (...) {
                ...
            }
        }
    }
    return sb.toString();
}
...

在上面的程式碼中,我們實現了一個名為getFileContent的方法,用於獲取對應檔案的內容;其中就使用了openFileInput來獲取檔案資料,並通過一系列的拼裝,最終返回整個檔案的內容。另外,我們需要了解一下,在Android系統中,檔案一般會儲存到和配置檔案同級的目錄下,只不過目錄名不是shared_prefs,而是files。更多關於Android檔案儲存的例子我們會在本書第7章中進行詳細介紹。

2.6.3 資料庫(SQLite)

關於資料庫的概念,我相信大家都已經非常熟悉了。Android系統給我們提供了一個強大的文字資料庫,即SQLite資料庫。它提供了與市面上的主流資料庫(如MySQL、SQLServer等)類似的幾乎所有的功能,包括事務(Transaction)。由於篇幅限制,我們不能在這裡介紹太多關於SQLite資料庫的內容,因此,如果大家想了解更多資訊請到SQLite的官方網站(http://www.sqlite.org)檢視。
與之前介紹的兩種資料儲存模式不同,資料庫的儲存方式偏向於存取的細節,比如,我們可以把同一型別的資料欄位定義好,並儲存到統一的資料表中去,進而可以針對每個資料進行更細節的處理。所以,如果可能的話,儘量使用資料庫來儲存資料,這樣會大大增強應用的結構性和擴充套件性。另外,我們還經常把SQLite資料庫和前面所提到的Android四大元件之一的“資料提供者”結合使用,因為它們對於“增刪查改”介面的定義和使用實際上是一致的。另外,我們在使用的過程中經常通過繼承SQLiteOpenHelper類並實現其中的抽象方法的形式來構造基礎的DB操作類,使用範例如程式碼清單2-16所示。
程式碼清單 2-16

...
public class DBHelper extends SQLiteOpenHelper {
    
    /* 資料庫配置 */
    private static final int DB_VERSION = 1;
    private static final String DB_NAME = "mydb.db";
    private static final String DB_TABLE = "mytable";
    
    /* 資料庫初始化和更新SQL */
    private static final String SQL_CREATE = "CREATE TABLE ...";
    private static final String SQL_DELETE = "DROP TABLE ...";
    
    /* 建構函式 */
    public DBHelper(Context context){
        super(context, DB_NAME, null, DB_VERSION);
    }
    
    /* 初始化資料庫 */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE);
    }
    
    /* 升級資料庫 */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(SQL_DELETE);
    }
}
...

此外,在需要使用的時候,我們可以通過getReadableDatabase和getWritableDatabase來獲取資料庫控制程式碼分別進行讀和寫的操作。另外,資料庫檔案會被存在shared_prefs和files的同級目錄下,目錄名為databases。關於SQLite資料庫的更多用法,我們也會在第7章中結合具體例項做進一步的介紹。


相關文章