Android – ViewModel Provider 如何正確取得ViewModel?
發布日期:2024/11/22
瀏覽次數:41
在 Android 開發中,ViewModel 是 MVVM 架構中負責管理 UI 資料邏輯的組件,常透過不同的方式來取得 ViewModel。以下是三種取得方式的詳細說明及適合的使用場景:
activityViewModels()
用法
private val viewModel: MyViewModel by activityViewModels()
特性
是 Jetpack Navigation 或 Fragment KTX 提供的擴充函數。
取得的是與宿主 Activity 共享的 ViewModel。
當 Fragment 與 Activity 需要共享資料時非常實用。
ViewModel 的生命週期與 宿主 Activity 一致,當 Activity 被銷毀時,ViewModel 也會被清除。
適用情境
需要在多個 Fragment 中共享資料,並且資料的管理由宿主 Activity 負責。
例如:Fragment A 和 Fragment B 都需要共享用戶的輸入或應用程式的狀態。
viewModels()
用法
private val viewModel: MyViewModel by viewModels()
特性
取得的是與當前 Fragment(或 Activity)相關聯的 ViewModel。
ViewModel 的生命週期與 Fragment 或 Activity 相同。
如果用在 Fragment 中,不會與其他 Fragment 或宿主 Activity 共享資料。
適用情境
當 ViewModel 只需要為單個 Fragment 或 Activity 提供邏輯與數據處理時使用。
例如:Fragment 單獨處理其自己的頁面邏輯(如表單驗證、API 請求等)。
ViewModelProvider(this)
用法
val viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
特性
是 Jetpack 原始的 ViewModel 工廠方法。
必須明確指定 ViewModel 的類型,例如 MyViewModel::class.java。
當 this 是 Activity 時,ViewModel 與 Activity 同生命週期;當 this 是 Fragment 時,ViewModel 與 Fragment 同生命週期。
需要手動處理工廠(ViewModelProvider.Factory)來提供參數化的 ViewModel。
適用情境
舊版本的 Android 開發中,或者需要完全自訂 ViewModel 初始化邏輯時使用。
若無法使用 KTX 提供的擴充函數(如 viewModels() 或 activityViewModels()),此方法仍然是基礎選擇。
選擇使用的指導原則
1. 需要跨 Fragment 共享資料:
使用 activityViewModels(),這樣可以保證所有 Fragment 與 Activity 共享相同的 ViewModel。
2. 單一 Fragment 或 Activity 使用:
使用 viewModels(),這樣可以讓 ViewModel 僅與單一 Fragment 或 Activity 綁定。
3. 高度客製化或不支援擴充函數:
使用 ViewModelProvider(this),尤其是在需要自訂初始化邏輯時。
其他補充
如果 ViewModel 需要特定的參數(例如 API token),通常需要實作自訂的 ViewModelProvider.Factory,而 viewModels() 和 activityViewModels() 都可以接受 factory 作為參數:
private val viewModel: MyViewModel by viewModels { MyViewModelFactory(token) }
Like