天天看點

【讀書筆記《Android遊戲程式設計之從零開始》】20.遊戲開發基礎(遊戲資料存儲)

對于資料的存儲,Android 提供了4種儲存方式。

(1)SharedPreference

此方法适用于簡單資料的保持,文如其名,屬于配置性質的儲存,不适合比較大的情況,預設存放在手機記憶體裡

(2)FileInputStream/FileOutputStream

此方式比較适合遊戲的儲存和使用,流檔案資料存儲可以保持較大的資料,而且通過此方式不僅能把資料存儲在手機記憶體中,也能将資料儲存到手機額SDcard中。

(3)SQLite

此方式也适合遊戲的儲存和使用,不僅可以儲存較大的資料,而且可以将自己的資料存儲到檔案系統或者資料庫當中,如SQLite資料庫,也能将資料儲存到SDcard 中。

(4)ContentProvider

此方式不推薦用于遊戲儲存,雖然此方式能存儲較大資料,還支援多個程式之間的資料進行交換,但遊戲中基本就不可能去通路外部應用程式的資料。

1.SharedPreference

SharedPreference 執行個體是通過Context 對象得到的:

Context.getSharePreference(String name,int mode)

作用:利用Context 對象擷取一個SharedPreference 執行個體

參數1:生成保持記錄的檔案名

參數2:操作模式

SharedPreference 執行個體的操作模式一共有四種:

Context.MODE_PRIVATE:新内容覆寫原内容。

Context.MODE_APPEND:新内容追加到原内容後。

Context.MODE_WORLD_READABLE:允許其他應用程式讀取。

Context.MODE_WORLD_WRITEABLE:允許其他應用程式寫入,會覆寫原資料。

SharedPreference 常用函數:

getFloat(String key,float defValue)

getInt(String key,int defValue)

getLong(String key,long defValue)

getString(String key,String defValue)

getBoolean(String key,boolean defValue)

SharedPreference 常用函數的作用是擷取存儲檔案中的值,根據方法不同擷取不同對應的類型值,一般第一個參數為索引Key值,第二個參數為在存儲檔案中找不到對應 value 值時,預設的傳回值。

對應的,在對存儲檔案的資料進行存入操作時,首先需要利用 SharedPreference 執行個體得到一個編輯對象:

SharedPreference.Editor edit;

得到編輯對象後就可以對 SharedPreference 中的資料進行操作。

SharedPreference.Editor.putFloat(arg0,arg1)

SharedPreference.Editor.putInt(arg0,arg1)

SharedPreference.Editor.putLong(arg0,arg1)

SharedPreference.Editor.putString(arg0,arg1)

SharedPreference.Editor.putBoolean(arg0,arg1)

以上方法的作用是對存儲的資料進行操作(寫入、儲存),其中第一個參數是需要儲存資料額Key值索引,第二個參數是需要儲存的資料。 

到此進行了儲存和修改,還需要将其編輯的資料進行送出方可完成存入和修改:

SharedPreference.Editor.commit() 

如果想删除存儲檔案中的一條資料,可以使用以下函數:

SharedPreference.Editor.clear()

下面用一個簡單小遊戲進行說明,先看下效果圖:

【讀書筆記《Android遊戲程式設計之從零開始》】20.遊戲開發基礎(遊戲資料存儲)

 建立項目,遊戲架構為 SurfaceView 遊戲架構,修改 MySurfaceView 類如下:

 View Code

2.流檔案存儲

利用前面 SharedPreference 的例子,去除 SharedPreference 存儲部分,改用流檔案形式進行儲存,隻需要修改其中“儲存”和“讀取”操作,也就是修改“按鍵事件”:

<a></a>

不管是讀入還是寫入,都是通過Activity 打開流檔案得到輸入輸出流。當需要寫入流檔案時,如果打開的流檔案不存在,那麼Android 會自動生成對應的流檔案;而當需要讀入流檔案時,首先應判斷流檔案是否存在,一旦流檔案不存在,就會抛出異常。

這裡的流形式的儲存操作比較簡單,需要注意的是:

● 讀流時,一定要記得判斷是否存在需要操作的流檔案;

● 寫入和讀入的資料類型要配對,順序也不能錯;例如:寫入時,先寫入了一個 Int值,然後又寫入了一個String 值;那麼讀入時,也應該先讀 Int 類型,然後再讀 String 類型;

● 流一旦打開一定要關閉,為了避免流操作出現異常,需確定正常關閉流,應該将關閉操作寫在finally 語句中;

● file 流使用 Data 流進行了封裝,這樣做的原因是可以獲得更多的操作方式,便于對資料的處理。

以上是使用流檔案的儲存方式,但是也隻是将儲存後的流檔案預設放在了系統記憶體裡。一般遊戲的資料可能會有很多,是以不應該放在手機記憶體中,而是放在 SDCard 中,這樣就不要擔心系統因遊戲儲存的資料過多導緻記憶體不足等問題。

将流檔案儲存在 SDCard 中的詳細步驟如下:

(1)聲明讀取權限:

Android 中的一些操作,比如:讀取通訊錄資訊、發送資訊、使用聯網、GPRS等功能都需要在項目 AndroidManifest.xml 中聲明使用權限,然後才可以正常使用其功能。

當然在很多時候,是不知道是否需要聲明添權重限的,其實這個也不用知道,因為如果用到這些需要聲明權限的功能,且恰好沒有聲明的情況下,在LogCat 中是會報異常的,其異常則提醒需要添加對應的權限。

寫入權限如下:

(2)建立目錄和存儲檔案

 使用 SDCard 的方式進行存儲資料,寫入的時候 Android 不會跟存儲系統預設路徑那樣預設生成存儲檔案,是以必須自己來建立;如果存儲的檔案有自定義路徑的話,那麼這個路徑也需要手動添加。

假定存儲檔案在 SDCard 的路徑為 /sdcard/yc/save.yc 。

① 首先需要建立路徑 /sdcard/yc

boolean File.exists()

 作用:判斷是否存在目前目錄

傳回值:目前目錄存在傳回true

boolean File.mkdirs()

作用:建立一個目錄

傳回值:當建立成功傳回true

②然後建立存儲檔案:/sdcard/yc/save.yc

boolean File.createNewFile()

作用:建立一個檔案

傳回值:建立成功傳回true

(3)通過加載指定路徑的存儲檔案擷取輸入輸出流

● 輸入流:FileInputStream fis = new FileInputStream(File file);

● 輸出流:FileOutputStream fos = new FileOutputStream(File file);

除此之外還需要知道一點,因為有時手機并沒有安裝 SDCard ,或者目前SDCard 處于被移除的狀态時,為了避免這兩種情況帶來的異常,需要通過下面方法擷取目前手機裝置SDCard 的狀态:

String Environment.getExternalStorageStorageState()

作用:擷取目前SDCard的狀态

傳回值:目前 SDCard 不存在時,傳回null ;當 SDCard 處于移除狀态時,傳回“removed”;

是以當預設手機裝置存在 SDCard 時,儲存在 SDCard 中 ;當 SDCard 不存在或者正處于被移除的狀态時,預設将資料儲存在手機記憶體中。上面的“按鍵事件”修改如下:

3.SQLite 輕量級資料庫

SQLite是一款輕量級資料庫,它的設計目的是嵌入式,而且它占用的資源非常少,在嵌入式裝置中,隻需要幾百KB!

SQLite的特性:

輕量級:使用 SQLite 隻需要帶一個動态庫,就可以享受它的全部功能,而且那個動态庫的尺寸想當小。

獨立性:SQLite 資料庫的核心引擎不需要依賴第三方軟體,也不需要所謂的“安裝”。

隔離性:SQLite 資料庫中所有的資訊(比如表、視圖、觸發器等)都包含在一個檔案夾内,友善管理和維護。

跨平台:SQLite 目前支援大部分作業系統,不至電腦作業系統更在衆多的手機系統也是能夠運作,比如:Android。

多語言接口:SQLite 資料庫支援多語言程式設計接口。

安全性:SQLite 資料庫通過資料庫級上的獨占性和共享鎖來實作獨立事務處理。這意味着多個程序可以在同一時間從同一資料庫讀取資料,但隻能有一個可以寫入資料.

優點:1.能存儲較多的資料。2.能将資料庫檔案存放到SD卡中! 

什麼是 SQLiteDatabase? 

     一個 SQLiteDatabase 的執行個體代表了一個SQLite 的資料庫,通過SQLiteDatabase 執行個體的一些方法,我們可以執行SQL 語句,對數        據庫進行增、删、查、改的操作。需要注意的是,資料庫對于一個應用來說是私有的,并且在一個應用當中,資料庫的名字也是惟一的。

什麼是 SQLiteOpenHelper ?

     根據這名字,我們可以看出這個類是一個輔助類。這個類主要生成一個資料庫,并對資料庫的版本進行管理。當在程式當中調用這個類的方法getWritableDatabase(),或者getReadableDatabase()方法的時候,如果當時沒有資料,那麼Android 系統就會自動生成一個資料庫。SQLiteOpenHelper 是一個抽象類,我們通常需要繼承它,并且實作裡邊的3 個函數

什麼是 ContentValues 類?

     ContentValues 類和Hashmap/Hashtable 比較類似,它也是負責存儲一些名值對,但是它存儲的名值對當中的名是一個String 類型,而值都是基本類型。

什麼是 Cursor ?

     Cursor 在Android 當中是一個非常有用的接口,通過Cursor 我們可以對從資料庫查詢出來的結果集進行随機的讀寫通路。

同樣利用前面 SharedPreference 的例子,去除 SharedPreference 存儲部分,改用SQLite進行儲存。

① 首先建立一個類MySQLiteOpenHelper繼承SQLiteOpenHelper;寫一個構造,重寫兩個函數:

② 在MySurfaceView類中建立對應的執行個體

③ 在SurfaceView初始化函數中執行個體一個資料庫輔助器

④ 最後修改按鍵監聽事件,其實隻需要修改其中“儲存”和“讀取”操作,代碼如下:

說明:

在Android中查詢資料是通過Cursor類來實作的,當我們使用SQLiteDatabase.query()方法時,會得到一個Cursor對象,Cursor指向的就是每一條資料。它提供了很多有關查詢的方法,具體方法如下:

 以下是方法和說明: 

 move    以目前的位置為參考,将Cursor移動到指定的位置,成功傳回true, 失敗傳回false 

 moveToPosition 将Cursor移動到指定的位置,成功傳回true,失敗傳回false 

 moveToNext  将Cursor向前移動一個位置,成功傳回true,失敗傳回false 

 moveToLast    将Cursor向後移動一個位置,成功傳回true,失敗傳回 false。 

 movetoFirst  将Cursor移動到第一行,成功傳回true,失敗傳回false 

 isBeforeFirst     傳回Cursor是否指向第一項資料之前 

 isAfterLast  傳回Cursor是否指向最後一項資料之後 

 isClosed          傳回Cursor是否關閉

 isFirst    傳回Cursor是否指向第一項資料 

 isLast       傳回Cursor是否指向最後一項資料 

 isNull       傳回指定位置的值是否為null 

 getCount     傳回總的資料項數 

 getInt          傳回目前行中指定的索引資料

本文轉自葉超Luka部落格園部落格,原文連結:http://www.cnblogs.com/yc-755909659/p/4223999.html,如需轉載請自行聯系原作者