【翻譯】安卓架構元件(5)-ViewModel
相關文章:
- 【翻譯】安卓架構元件(1)-App架構指導
- 【翻譯】安卓架構元件(2)-新增元件到你的專案中
- 【翻譯】安卓架構元件(3)-處理生命週期
- 【翻譯】安卓架構元件(4)-LiveData
- 【翻譯】安卓架構元件(6)-Room持久化類庫
- 【翻譯】安卓架構元件(7)-分頁庫
ViewModel
被設計用於儲存並管理UI相關的資料,因此可以在配置變化時存活下來,例如當螢幕旋轉的時候。
app元件,例如Activity
和Fragment
擁有可以被安卓框架所管理的生命週期。框架可以決定銷燬或建立它們,這是基於一些使用者的行為或者裝置的事件,而這一切都在你的控制範圍外。
因為一些物件可能會被作業系統銷燬或重新建立,任何你所持有的資料都會丟失。例如,你的Activity
擁有一組使用者列表,當Activity
由於配置變化而重新建立時,新的Activity
不得不重新獲取使用者列表。對於簡單的資料,Activity
可以使用onSaveInstanceState()
方法並從onCreate()
的bundle
裡恢復資料,但是這種方法僅僅適合於少量資料,例如UI狀態,不適用於大量資料,例如一組使用者列表。
另一個問題是,這些UI控制器(Activity
、Fragment
等)需要頻繁地非同步呼叫,可能會需要一些時間返回。UI控制器需要管理這些呼叫,並當被銷燬的時候清除它們,以避免潛在的記憶體洩漏。這需要很多的程式碼維護,並且在由於配置變化而重新建立的情況下是很浪費資源的,因為需要重新進行相同的呼叫。
另外,這些UI控制器已經響應使用者行為或處理作業系統互動。當它們也需要手動處理資源的時候,會使得類急速膨脹。上帝的Activity或上帝的Fragment,是指一個試圖處理所有app工作的單獨類,而不是分派到其他類去完成。這樣也會使得測試工作很難進行。
將我們的UI和控制邏輯分離變得越來越容易和高效了。Lifecycle
提供了一個新類叫做ViewModel
,一個負責為UI準備資料的幫助類。ViewModel
會在配置發生變化的時候自動儲存,所以其所持有的資料會在新的Activity
或新的Fragment
立即可用。在上面我們所提及的例子中,應當是ViewModel
的職責來獲取並保持使用者列表,而不是Activity
或Fragment
。
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<Users>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// 非同步呼叫獲取使用者列表
}
}
現在新的Activity
如下:
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// 更新 UI
});
}
}
如果Activity
被重新建立了,它會收到被之前Activity
建立的相同MyViewModel
例項。當所屬Activity
終止後,框架呼叫ViewModel
的onCleared()
方法清除資源。
因為
ViewModel
在指定的Activity
或Fragment
例項外存活,它應該永遠不能引用一個View,或持有任何包含Activity context
引用的類。如果ViewModel
需要Application
的context(如獲取系統服務),可以擴充套件AndroidViewmodel
,並擁有一個構造器接收Application
。
在Fragment
間共享資料
一個Activity
中的多個Fragment
相互通訊是很常見的。每個Fragment
需要定義介面描述,所屬Activity
將二者捆綁在一起。此外,每個Fragment
必須處理其他Fragment
未建立或不可見的情況
通過使用ViewModel
可以解決這個痛點。想象一種情況,一個Fragment
從列表項中選擇一項,在另一個Fragment
顯示被選中項的內容。
這些Fragment
可以使用它們的Activity
共享ViewModel
來處理通訊:
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onActivityCreated() {
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends LifecycleFragment {
public void onActivityCreated() {
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// update UI
});
}
}
請注意,兩個Fragment
都使用了getActivity()
,以通過ViewModelProviders
獲取SharedViewModel
。
這種方式的好處包括:
-
Activity
不需要做任何事情,也不需要知道通訊的事情 -
Fragment
不需要知道彼此,除了SharedViewModel
進行聯絡。如果它們(Fragment
)其中一個消失了,其餘的仍然能夠像往常一樣工作 - 每個
Fragment
有自己的生命週期,而且不會受其它Fragment
生命週期的影響。事實上,一個Fragment
替換另一個Fragment
,UI的工作也不會受到任何影響。
ViewModel的生命週期
ViewModel
物件的範圍由獲取ViewModel
時傳遞至ViewModelProvider
的Lifecycle
所決定。ViewModel
始終處在記憶體中,直到Lifecycle
永久地離開—對於Activity
來說,是當它終止(finish)的時候,對於Fragment
來說,是當它分離(detached)的時候。
相關文章
- 剖析 Android 架構元件之 ViewModelAndroid架構元件View
- Android 官方架構元件(三)——ViewModelAndroid架構元件View
- 改造 Android 官方架構元件 ViewModelAndroid架構元件View
- 初學 Android 架構元件之 ViewModelAndroid架構元件View
- Android 架構元件 - Lifycycle, LiveData, ViewModelAndroid架構元件LiveDataView
- 【AAC 系列四】深入理解架構元件:ViewModel架構元件View
- Jetpack架構元件學習(2)——ViewModel和Livedata使用Jetpack架構元件ViewLiveData
- Android官方架構元件ViewModel:從前世今生到追本溯源Android架構元件View
- Android官方架構元件之LiveData + ViewModel + Room 原始碼分析一Android架構元件LiveDataViewOOM原始碼
- 翻譯:展示元件和容器元件元件
- Apache Hadoop文件翻譯之一(HDFS架構)ApacheHadoop架構
- Unity應用架構設計(5)——ViewModel之間如何共享資料Unity應用架構View
- 安卓應用安全指南翻譯完成安卓
- 安卓架構文章合集安卓架構
- 安卓系統架構安卓架構
- Android架構元件:用ViewModelCommandLiveData處理ViewModel中的事件釋出Android架構元件ViewLiveData事件
- [翻譯] 全SDDC架構的採用仍遙不可及架構
- docker官方文件翻譯5Docker
- 【翻譯】.NET 5 Preview5釋出View
- 詳解安卓架構入門安卓架構
- RabbitMQ 元件和架構MQ元件架構
- 元件化 構架思路元件化
- 新架構元件: WorkManager架構元件
- [翻譯] NVIDIA HugeCTR,GPU 版本引數伺服器 --(10)--- 推理架構GPU伺服器架構
- [翻譯]用 Puppet 搭建易管理的伺服器基礎架構(4)伺服器架構
- [翻譯]用 Puppet 搭建易管理的伺服器基礎架構(3)伺服器架構
- [翻譯]用 Puppet 搭建易管理的伺服器基礎架構(1)伺服器架構
- [翻譯]用 Puppet 搭建易管理的伺服器基礎架構(2)伺服器架構
- Ambari 架構(譯文)架構
- [譯]Facebook的架構架構
- 【翻譯】記憶體結構 (一)記憶體
- 安卓第二夜 有趣的架構安卓架構
- [譯] Architecture Components 之 ViewModelView
- 【翻譯】.NET 5 Preview8釋出View
- 【翻譯】.NET 5 Preview7釋出View
- 【翻譯】.NET 5中的效能改進
- 【翻譯】.NET 5 RC1釋出
- 5 Java NIO Scatter 與Gather-翻譯Java