Android開發 -- Jetpack 之 ViewModel 是什麼【使用、快速入門、通俗解釋】

全文閱讀預計 10 分鐘

這可能是你看過的最清晰明瞭的講解

主題 👇

寫在前面:由於 ViewModelLiveData 關聯性強,在學習 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

發佈了15 篇原創文章 · 獲贊 7 · 訪問量 3003
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章