將lifecycle-*相關依賴升級到2.2.0時,項目中的ViewModelProviders顯示被棄用
查看官方文檔發(fā)現(xiàn):

需要使用 ViewModelProvider(ViewModelStoreOwner) 方法代替
這里的ViewModelStoreOwner是一個接口,F(xiàn)ragment和Activity都實現(xiàn)了該接口,所以直接傳以前的參數就可以
全局替換(ctrl+shift+r)依賴和改行代碼,完事
求豆麻袋!事情并沒有這么簡單
應用啟動就會崩潰,報如下錯誤:
java.lang.RuntimeException:Cannot create an instance of class **ViewModel
cause:java.lang.Class<*ViewModel> has no zero argument constructor
無法創(chuàng)建ViewModel,提示ViewModel沒有無參構造函數
擼一把源碼看看到底哪里出了問題,官方總不能給個沒法用的東西
在Android中使用ViewModel一般是通過繼承AndroidViewModel進行使用,而AndroidViewModel只有一個構造方法:
public AndroidViewModel(@NonNull Application application) {
mApplication = application;
}
而其父類ViewModel類本身是沒有構造方法的,即默認實現(xiàn)了無參構造方法,而AndroidViewModel則不存在無參構造方法
所以第一個解決辦法就是直接使用ViewModel來代替AndroidViewModel(沒有具體試過,應該是可以的)
但是使用AndroidViewModel肯定也是有相應的解決辦法的,那就需要繼續(xù)看ViewModelProvider的源碼,在創(chuàng)建ViewModel時調用了以下的方法:
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) {
//這里調用到了另一個構造方法,第一個參數為Fragment或者Activity;
//對于第二個參數來說,F(xiàn)ragemnt和Activtiy沒有實現(xiàn)HasDefaultViewModelProviderFactory這個接口,所以對于這種情況來說,就是調用了 NewInstanceFactory.getInstance()來生成一個工廠
this(owner.getViewModelStore(), owner instanceof HasDefaultViewModelProviderFactory
? ((HasDefaultViewModelProviderFactory) owner).getDefaultViewModelProviderFactory()
: NewInstanceFactory.getInstance());
}
繼續(xù)往下看,NewInstanceFactory類中出現(xiàn)了這樣一行注釋:
/**
* Simple factory, which calls empty constructor on the give class.
*/
在該工廠類的create方法中也直接調用了
return modelClass.newInstance();
ok,既然找到了問題,就肯定要找到解決的辦法,貼心的官方在該類下方直接就跟著AndroidViewModelFactory類,繼承自該類,其中比該類多了application相關的操作,并且調用了以Application為單獨參數的構造方法
那么完美解決辦法就是在使用ViewModelProvider時多傳一個參數,即AndroidViewModelFactory的實例,完整代碼如下:
mViewModel= ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(application))[XXXViewModel::class.java]