java.lang.InstantiationException <com.example.MyViewModel> 在使用 SavedStateViewModelFactory 时没有零



我只是试着按照本指南来了解MVVM体系结构:https://developer.android.com/jetpack/guide

我的问题是:当我在ViewModel类中使用两个参数时"SavedStateHangle";以及";UserRepository";,然后我的应用程序崩溃,出现以下错误:

E/AndroidRuntime:在android.app.servertransaction.LaunchActivityItem.exexecute(LaunchActivityItem.java:78)在android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)在android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)在android.app.ActivityThread$H.handleMessage(ActivityThreads.java:1955)在android.os.Handler.dispatchMessage(Handler.java:106)在android.os.Looper.loop(Looper.java:214)在android.app.ActivityThread.main(ActivityThreads.java:7058)位于java.lang.reflect.Method.ioke(本机方法)网址:com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)网址:com.android.internal.os.ZygoteInit.main(ZygoteNit.java:965)引起原因:java.lang.InstructionException:java.lang.Class<ru.itschool.jetpackguide.UserProfileViewModel>在java.lang.Class.newInstance(Native Method)中没有零参数构造函数在androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219)

如果我从构造函数参数中删除UserRepository(并且构造函数只有SavedStateHandle),那么片段就可以工作(没有UserRepository,但它不会因此错误而崩溃)。

我将ViewModel与SavedStateViewModelFactory和Hilt+Dagger库一起使用,就像Android应用程序体系结构指南中一样。

我在UserProfileFragment:上用这段代码创建我的ViewModel

private val viewModel : UserProfileViewModel
by viewModels(
factoryProducer = {SavedStateViewModelFactory(activity?.application, this, defaultBundle())}
)

和我的ViewModel代码:

@HiltViewModel
class UserProfileViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
userRepository: UserRepository
) : ViewModel() {
var userId: String = savedStateHandle["uid"]
?: throw IllegalArgumentException("Missing user ID")
private val _user = MutableLiveData<User>()
val user : LiveData<User> = _user
init {
viewModelScope.launch {
_user.value = userRepository.getUser(userId)
}
}
}

你可以在这里找到我项目的完整代码。也许有人在我之前实施了这个指南,并且已经知道答案了?:)

当您为ViewModel提供工厂时,如果ViewModel的实例还不存在,则为viewModels提供了一种创建实例的方法。SavedStateViewModelFactory只提供了一种用SavedStateHandle实例化ViewModel的方法,如果没有您的一些工作,它显然不知道如何提供自定义存储库。

因此,为了给它所需的帮助,您可能应该考虑创建ViewModelProvider.Factory的自定义实现,这需要您实现create方法:

class VMF: ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {}
}

对于您的示例,假设您想要ViewModel中可用的片段参数,简化的实现将是:

class VMF(private val userRepository: UserRepository, private val args: Bundle?): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if(UserProfileViewModel::class.java.isAssignableFrom(modelClass)) {
return UserProfileViewModel(userRepository, args)
}
...
}
}

然后你会用你的工厂来代替默认的工厂:

private val viewModel : UserProfileViewModel by viewModels {
VMF(userRepository, arguments)
}

尽管这个答案并不完全适用于@Eldar Kurbanov的情况?你们中的任何人可能只是忘记了视图模型上方的@HiltViewModel注释。

相关内容

  • 没有找到相关文章

最新更新