全文閱讀預計 10 分鐘
這可能是你看過的最清晰明瞭的講解
主題 👇
寫在前面:由於
ViewModel
與LiveData
關聯性強,在學習ViewModel
的時候要結合LiveData
同時學習
想要快速學習 LiveData ?請進入此鏈接學習我對於 LiveData 的快速及通俗講解。 全文閱讀預計 15 分鐘。
官方定義:
ViewModel
類旨在以注重生命週期
的方式存儲和管理界面相關的數據
。ViewModel
類讓數據可在發生屏幕旋轉等配置更改
後繼續存在
問題來源(1):例如你的
APP
某個Activity
中包含一個列表
,因爲配置更改而重新創建Activity
後(例如衆所周知的屏幕旋轉發生後需手動保存數據在旋轉後進行恢復)
,新Activity
必須重新
提取列表數據,對於簡單數據,Activity
可以使用onSaveInstanceState()
方法從onCreate()
中的捆綁包恢復數據,但這種方法僅適合可以序列化再反序列化但少量數據
,不適合數量可能較大但數據,如用戶列表或位圖
問題來源(2):我們通常需要調用網絡接口數據,網絡數據需要一段時間才能返回結果,而我們需要管理這些調用,並確保系統
銷燬後清理這些調用
來避免內存泄漏
,項目內容的日益增多會使開發者花費大量時間進行維護,並且在因爲配置更改重新創建對象的情況下(例如上面說的屏幕旋轉的例子)
,會造成資源浪費,因爲對象可能需要重新發出已經發出過的調用
所以,從界面控制器
(Activity、Fragment 等)
分離出試圖數據所有權的做法更易行、高效且勢在必行
使用 👇
引入 ViewModel
// build.gradle
dependencies {
// ViewModel and LiveData
def lifecycle_version = "2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
// 或
// implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
// 前者創建一個變量主要是便於管理,假如說你還引入了 lifecycle 的其它東西那麼他們都同時使用這個變量的版本號就好,以後升級版本的時候只需要改一個地方
}
需求實踐
我們做一個模擬服務器獲取一個列表數據並展示到
RecyclerView
上的例子
第一步:
// 創建一個 ViewModel 類
public class FourViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUserList() {
if (users == null) {
users = new MutableLiveData<>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Handler 只爲了模擬,你可以在這裏通過你的網絡框架 OkHttp、Retrofit 等進行網絡操作
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
List<User> list = new ArrayList<>();
list.add(new User());
// ... 添加多個測試數據
list.add(new User());
users.setValue(list);
}
}, 2000);
}
}
第二步:
// 將 Activity 繼承自 AppCompatActivity
public class FourActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
FourViewModel model = ViewModelProviders.of(this).get(FourViewModel.class);
model.getUserList().observe(this, new Observer<List<User>>() {
@Override
public void onChanged(List<User> users) {
// recyclerView.setLayoutManager...
// recyclerView.setAdapter...
}
});
}
}
ViewModel
是什麼:它相當於界面控制器
的輔助程序類,負責爲界面準備數據,在配置更改期間會自動保留ViewModel
對象,便於他們存儲的數據立即可供下一個Activity、Fragment
實例使用。例如上面的例子
:如果您需要在應用中顯示用戶列表,請確保將獲取和保留該用戶列表的責任分配給ViewModel
而不是Activity、Fragment
!!!ViewModel 絕不能引用視圖、Lifecycle 或可能存儲對 Activity 上下文對引用對任何類!!!
ViewModel
對象存在的時間比視圖或LifecycleOwners
的特定實例存在的時間更長。還意味着,你可以更輕鬆地編寫涵蓋ViewModel
的測試,因爲它不瞭解視圖和Lifecycle
對象。ViewModel
對象可以包含LifecycleObservers
,如LiveData
對象。但是,ViewModel
對象絕不能觀察對生命週期感知型可觀察對象(如LiveData
對象)的更改。 如果ViewModel
需要Application
上下文(例如,爲了查找系統服務),它可以擴展AndroidViewModel
類並設置用於接收Application
的構造函數,因爲Application
類會擴展Context
。
// 也就是說如果你想用 context 可以繼承自 AndroidViewModel
// 就可以得到 Application 對象了再通過 Application 獲取 context
public class FourViewModel extends AndroidViewModel {
public FourViewModel(@NonNull Application application) {
super(application);
// do something...
}
}
文末 👇
OK,到這裏就是 ViewModel 入門講解了,你會發現代碼變多了,但是仔細想想,當我們接手別人項目的時候最難懂的是什麼:是混亂的邏輯
。上面的代碼量雖然多了一點,但使代碼的邏輯變得清晰
了,何嘗不是一件好事呢~
在此,你已經在極少對時間內對於 ViewModel
有了新的認識,現在我推薦你學習如何通過 MVVM框架
來編寫以後的代碼,它的優勢是使你的代碼邏輯更加清晰以減少開發時間。
想要快速學習 MVVM
框架?請進入此鏈接學習我對於 MVVM 的快速及通俗講解。 全文閱讀預計 10 分鐘。
碼字不易,還請動動小手左側欄中點贊 👍,3Q