Cannot create an instance of class AndroidViewModel (androidx ViewModelProvider AndroidViewModel)
Posted Eli Shaw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cannot create an instance of class AndroidViewModel (androidx ViewModelProvider AndroidViewModel)相关的知识,希望对你有一定的参考价值。
使用 androidx viewmodel 2.2.0 后,对 ViewModel 的创建有一些变化
原:ViewModelProviders.of(activity).get(ViewModel.class)
被替换为:ViewModelProvider(activity).get(ViewModel.class)
而使用 ViewModelProvider 创建继承自 AndroidViewModel 的类会报错 Cannot create an instance of class AndroidViewModel
原因是无法创建带参数的构造方法,原因是 ViewModelProvider 默认创建无参的构造方法,如果有参数的构造方法将无法正常创建。而 AndroidViewModel 需要使用带 application 参数的构造方法创建,解决办法是使用 AndroidViewModelFactory 创建 AndroidViewModel。如下
ViewModelProvider(
activity,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(ViewModel.class)
如果你需要创建更多参数的构造方法,需要自定义 AndroidViewModelFactory,如下是多了一个 String 型的AndroidViewModelFactory
class AndroidViewModelFactory private constructor(
private val mApplication: Application,
private val mName: String
) : ViewModelProvider.NewInstanceFactory()
override fun <T : ViewModel?> create(modelClass: Class<T>): T
return if (AndroidViewModel::class.java.isAssignableFrom(modelClass))
try
modelClass.getConstructor(
Application::class.java, String::class.java
).newInstance(mApplication, mName)
catch (e: Exception)
throw RuntimeException("Cannot create an instance of $modelClass", e)
else super.create(modelClass)
companion object
private var sInstance: AndroidViewModelFactory? = null
fun getInstance(
application: Application,
name: String
): AndroidViewModelFactory
if (sInstance == null)
sInstance = AndroidViewModelFactory(application, name)
return sInstance as AndroidViewModelFactory
使用方式如下
ViewModelProvider(
activity,
AndroidViewModelFactory.getInstance(application, name)
).get(ViewModel.class)
另附上我创建 ViewModel 的方式
1.AndroidViewModelFactory
class AndroidViewModelFactory private constructor(
private val mApplication: Application,
private val mName: String
) : ViewModelProvider.NewInstanceFactory()
override fun <T : ViewModel?> create(modelClass: Class<T>): T
return if (AndroidViewModel::class.java.isAssignableFrom(modelClass))
try
modelClass.getConstructor(
Application::class.java, String::class.java
).newInstance(mApplication, mName)
catch (e: Exception)
throw RuntimeException("Cannot create an instance of $modelClass", e)
else super.create(modelClass)
companion object
private var sInstance: AndroidViewModelFactory? = null
fun getInstance(
application: Application,
name: String
): AndroidViewModelFactory
if (sInstance == null)
sInstance = AndroidViewModelFactory(application, name)
return sInstance as AndroidViewModelFactory
2.ViewModelFactory
/**
* @author: Eli Shaw
* @Date: 2020-04-27 17:20:45
* @Description:创建相应的 ViewModel
*/
object ViewModelFactory
/**
* @Description: 创建 FragmentActivity 页面的 ViewModel
* @Author: Eli
* @Date: 2020-05-09 14:41:04
*/
fun <T : ViewModel?> createViewModel(
activity: FragmentActivity,
cls: Class<T>?
): T
return ViewModelProvider(activity).get(cls!!)
/**
* @Description: 创建 Fragment 页面的 ViewModel
* @Author: Eli
* @Date: 2020-05-09 14:40:36
*/
fun <T : ViewModel?> createViewModel(
fragment: Fragment,
cls: Class<T>?
): T
return ViewModelProvider(fragment).get(cls!!)
/**
* @Description:创建 FragmentActivity 页面的 AndroidViewModel
* @Author: Eli
* @Date: 2020-05-09 14:36:39
*/
fun <T : ViewModel?> createViewModel(
activity: FragmentActivity,
application: Application,
cls: Class<T>?
): T
return ViewModelProvider(
activity,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(cls!!)
/**
* @Description:创建 Fragment 页面的 AndroidViewModel
* @Author: Eli
* @Date: 2020-05-09 14:36:39
*/
fun <T : ViewModel?> createViewModel(
fragment: Fragment,
application: Application,
cls: Class<T>?
): T
return ViewModelProvider(
fragment,
ViewModelProvider.AndroidViewModelFactory.getInstance(application)
).get(cls!!)
/**
* @Description: 创建带参数的 AndroidViewModel
* @Author: Eli
* @Date: 2020-05-09 14:36:24
*/
fun <T : ViewModel?> createViewModel(
activity: FragmentActivity,
application: Application,
name: String,
cls: Class<T>?
): T
return ViewModelProvider(
activity,
AndroidViewModelFactory.getInstance(application, name)
).get(cls!!)
3.NameViewModel
class NameViewModel(application: Application, name: String) : AndroidViewModel(application)
val name = ObservableField<String>()
init
this.name.set(name)
4.NameActivity
class NameActivity : AppCompatActivity()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
val binding =
DataBindingUtil.setContentView(this, R.layout.activity_name) as ActivityNameBinding
val viewModel = ViewModelFactory.createViewModel(
this,
application,
"AndroidViewModel",
NameViewModel::class.java
)
binding.viewModel = viewModel
5.activity_name
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="cn.eli.demo.viewmodel.NameViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".viewmodel.NameActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="@viewModel.name"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
以上是关于Cannot create an instance of class AndroidViewModel (androidx ViewModelProvider AndroidViewModel)的主要内容,如果未能解决你的问题,请参考以下文章
java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxxViewModel
java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxxViewModel
java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxxViewModel
java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxxViewModel
java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxxViewModel
Cannot create an instance of OLE DB provider “OraOLEDB.Oracle” for linked server "xxxxxxx"