1. 事前準備
本程式碼研究室將說明如何自行建構一款名為「Forage」的新應用程式。本程式碼研究室將引導您逐步完成 Forage 應用程式專案,包括在 Android Studio 中設定和測試專案。
必要條件
- 此專案適用於已完成 Android Kotlin 基本概念課程單元 5 的學員。
建構項目
- 實作實體、DAO、ViewModel 和資料庫類別,以便透過 Room 在應用程式中加入持續性機制。
軟硬體需求
- 已安裝 Android Studio 的電腦。
2. 已完成應用程式總覽
完成後的 Forage 應用程式可讓使用者追蹤他們在自然界中覓得的項目,例如食物。在使用 Room 的工作階段之間會保留此資料。您將運用所掌握的 Room 知識,以及對在資料庫執行讀取、寫入、更新及刪除作業的瞭解,在 Forage 應用程式中實現持續性。下文說明完成後的應用程式及其功能。
應用程式初次啟動時,使用者會看到空白畫面,其中包含顯示覓得項目的回收器檢視畫面,還有右下角可用來新增項目的浮動式按鈕。

新增項目時,使用者可以指定名稱、找到項目的地點,並加上其他附註。你也可以有核取方塊,以指定食品是否屬於當季。

新增的項目將顯示在第一個畫面的回收器檢視畫面中。

輕觸某個項目就會開啟詳細資料畫面,並顯示名稱、地點和附註。

浮動式按鈕也會從加號變更為編輯圖示。輕觸此按鈕即可開啟畫面,以便編輯名稱、地點、附註和「當季」核取方塊。輕觸刪除按鈕則可從資料庫中移除項目。

雖然系統已導入此應用程式的使用者介面部分,但您的任務是運用對 Room 的瞭解來實現持續性,讓應用程式能夠讀取、寫入、更新及刪除資料庫中的項目。
3. 開始操作
下載專案程式碼
請注意,資料夾名稱是 android-basics-kotlin-forage-app。在 Android Studio 中開啟專案時,請選取這個資料夾。
如要取得這個程式碼研究室的程式碼,並在 Android Studio 中開啟,請按照下列步驟操作:
取得程式碼
- 按一下上面顯示的網址。系統會在瀏覽器中開啟專案的 GitHub 頁面。
- 在專案的 GitHub 頁面中,按一下「Code」按鈕開啟對話方塊。

- 在對話方塊中,按一下「Download ZIP」按鈕,將專案儲存到電腦。等待下載作業完成。
- 在電腦中找到該檔案 (可能位於「下載」資料夾中)。
- 按兩下解壓縮 ZIP 檔案。這項操作會建立含有專案檔案的新資料夾。
在 Android Studio 中開啟專案
- 啟動 Android Studio。
- 在「Welcome to Android Studio」視窗中,按一下「Open an existing Android Studio project」。

注意:如果 Android Studio 已開啟,請依序選取「File」>「New」>「Import Project」選單選項。

- 在「Import Project」對話方塊中,前往解壓縮專案資料夾所在的位置 (可能位於「下載」資料夾中)。
- 按兩下該專案資料夾。
- 等待 Android Studio 開啟專案。
- 按一下「Run」按鈕
即可建構並執行應用程式。請確認應用程式的建構符合預期。 - 在「Project」 工具視窗中瀏覽專案檔案,查看應用程式的設定方式。
4. 設定專案以使用 Room
定義 Forageable 實體
專案已有 Forageable 類別,可定義應用程式的資料 (model.Forageable.kt)。此類別有多個屬性:id、name、address、inSeason 和 notes。
data class Forageable(
val id: Long = 0,
val name: String,
val address: String,
val inSeason: Boolean,
val notes: String?
)
不過,若要使用此類別儲存持續性資料,就需要將類別轉換為 Room 實體。
- 使用這個表格名稱為
"forageable_database"的@Entity為類別加上註解。 - 將
id屬性設定為主鍵。主鍵應由系統自動產生。 - 將
inSeason屬性的欄名稱設定為"in_season"。
實作 DAO
您將透過檢視模型存取資料庫,而 ForageableDao (data.ForageableDao.kt) 可用來定義從資料庫讀取及寫入資料庫的方法,就如同您的猜像。由於 DAO 只是您定義的介面,因此無需撰寫任何程式碼即可導入這些方法。您應該改用 Room 註解,視需要指定 SQL 查詢。
在 ForageableDao 介面中,您必須新增五個方法。
getForageables()方法會對資料庫中的所有資料列傳回Flow<List<Forageable>>。getForageable(id: Long)方法會傳回符合指定id的Flow<Forageable>。insert(forageable: Forageable)方法會將新的Forageable插入至資料庫中。update(forageable: Forageable)方法會採用現有Forageable作為參數,並據此更新資料列。delete(forageable: Forageable)方法會採用Forageable作為參數,然後從資料庫中將其刪除。
導入檢視模型
ForageableViewModel (ui.viewmodel.ForageableViewModel.kt) 已部分導入,但您必須新增可存取 DAO 方法的功能,才能實際讀取及寫入資料。請按照下列步驟導入 ForageableViewModel。
- 傳遞
ForageableDao例項時,應以類別建構函式中參數的形式傳遞。 - 建立
LiveData<List<Forageable>>類型的變數,此變數會使用 DAO 取得完整的Forageable實體清單,並將結果轉換為LiveData。 - 建立採用 ID (
Long類型) 做為參數的方法,此方法會在 DAO 上呼叫getForageable()方法,並將結果轉換為LiveData,藉此傳回LiveData<Forageable>。 - 在
addForageable()方法中,使用viewModelScope啟動協同程式,並使用 DAO 將Forageable例項插入至資料庫中。 - 在
updateForageable()方法中,使用 DAO 更新Forageable實體。 - 在
deleteForageable()方法中,使用 DAO 更新Forageable實體。 - 建立可透過
ForageableDao建構函式參數建立ForageableViewModel例項的ViewModelFactory。
導入資料庫類別
ForageDatabase (data.ForageDatabase.kt) 類別實際上是將實體和 DAO 公開給 Room。按照說明導入 ForageDatabase 類別。
- 實體:
Forageable - 版本:
1 - exportSchema:
false - 在
ForageDatabase類別中,加入能夠傳回ForageableDao的抽象函式 - 在
ForageDatabase類別中,用名為INSTANCE的私人變數和傳回ForageDatabase單例模式的getDatabase()函式定義夥伴模式物件。
- 在
BaseApplication類別中,建立使用延遲初始化功能傳回ForageDatabase例項的database屬性。
5. 保留及讀取片段中的資料
設定實體、DAO、檢視模型,以及定義要在 Room 公開的資料庫類別後,您只需要修改 Fragments,即可存取檢視模型。您必須在三個檔案中進行變更,各檔案用於應用程式中的各畫面。
Forageable 清單
Forageable 清單畫面只需要兩個項目:檢視模型的參照,以及對完整 Forageable 清單的存取權限。在 ui.ForageableListFragment.kt 中執行以下工作。
- 類別中已有
viewModel屬性。但不使用您在上一個步驟中定義的工廠函式。您必須先重構此宣告,才能使用ForageableViewModelFactory。
private val viewModel: ForageableViewModel by activityViewModels {
ForageableViewModelFactory(
(activity?.application as BaseApplication).database.foragableDao()
)
}
- 然後在
onViewCreated()中,從viewModel觀測allForageables屬性,並視需要在轉接程式上呼叫submitList()來填入清單。
Forageable 詳細資料畫面
對於 ui/ForageableDetailFragment.kt 中的詳細資料清單,您需要執行的動作幾乎完全相同。
- 轉換
viewModel屬性以正確初始化ForageableViewModelFactory。 - 在
onViewCreated()中,呼叫檢視模型上的getForageable(),並傳入id以取得Forageable實體。觀測動態資料並將結果設定為forageable屬性,然後呼叫bindForageable()來更新使用者介面。
新增及編輯 Forageable 畫面
最後,您需要在 ui.AddForageableFragment.kt 中執行類似操作。請注意,此畫面也會負責更新及刪除實體。不過,系統已從檢視模型的正確位置呼叫這些方法。您只需在此檔案中進行兩項變更即可。
- 再次重構
viewModel屬性以使用ForageableViewModelFactory。 - 在您調整刪除按鈕的顯示設定之前,請在
onViewCreated()的 if 陳述式區塊中,呼叫檢視模型上的getForageable(),並傳入id,然後將結果設定為forageable屬性。
這就是您需要在片段中執行的所有動作。您現在可以執行應用程式,藉此查看動作中的所有持續性功能。
6. 測試指示
執行測試
如要執行測試,請執行下列其中一項動作:
如果是單一測試案例,請開啟測試案例類別 PersistenceInstrumentationTests.kt,然後按一下類別宣告左側的綠色箭頭。然後,您可以從選單中選取「Run」選項。這麼做將會執行測試案例中的所有測試。

您通常只需要執行一項測試,例如在只有一個測試失敗,而其他測試都通過時。執行單一測試的做法,與執行整個測試案例一樣。使用綠色箭頭並選取「Run」選項。

如果您有多個測試案例,也可以執行整個測試套件。就像執行應用程式一樣,您可以在「Run」選單中找到這個選項。

請注意,Android Studio 會預設為您所執行的最後一個目標 (應用程式、測試目標等),因此如果選單仍顯示「Run」>「Run ‘app'」,您可以依序選取「Run」>「Run」執行測試目標。

然後從彈出式選單中選擇測試目標。
