java.lang.RuntimeException: 无法创建 class ViewModel 的实例

java.lang.RuntimeException: Cannot create an instance of class ViewModel

我正在尝试实例化一个 viewModel class,其中包含一个 init 块,我试图在其中发送带有截击的 Get 请求。问题是当我试图在我的 Fragment class 中实例化这个 class 时,我收到了这个错误,我不知道为什么。也许来自构造函数的上下文是问题所在?感谢:

视图模型class

class BooksFragmentViewModel(c : Context) : ViewModel() {

lateinit var cont: Context
var books: MutableLiveData<MutableList<BookItem>> = MutableLiveData<MutableList<BookItem>>()
var triggerAddBook = MutableLiveData<Boolean>()
var triggerDeleteBook = MutableLiveData<Boolean>()
var triggerEditBook = MutableLiveData<Boolean>()
var bookRepo: BookRepository = BookRepository()
var bookItemAdd: BookItem? = null
var bookItemDelete: BookItem? = null
var bookItemEdit : BookItem? = null
var bookNew: LiveData<BookItem> = Transformations.switchMap(triggerAddBook) {
    if (it != null && it)
        addBook()
    else
        null
}

  init {
        books = bookRepo.booksGetRequest(c)
    }

片段Class

class BooksFragment : Fragment(), BooksAdapter.OnDeleteBtnClicked, BooksAdapter.OnEditBtnClicked {
lateinit var booksModel: BooksFragmentViewModel
var position: Int = 0

private var adapter: BooksAdapter = BooksAdapter(this, this)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.fragment_books, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    booksModel = ViewModelProvider(requireActivity()).get(BooksFragmentViewModel::class.java)
    booksLoading_progressBar.visibility = View.VISIBLE
    var c: Context? = context
    if (c != null) {
        booksModel.setContext(c)
    }

如果你有一个带参数的 ViewModel(比如你的例子中的上下文),那么你需要使用 Factory 将任何参数传递给那个 ViewModel

 booksModel = ViewModelProvider(this,object :
        ViewModelProvider.Factory{
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            return booksModel(requireActivity()) as T
        }
    }).get(booksModel::class.java)

问题确实是因为带参数的主构造函数。您要求 ViewModelProvider 创建 BooksFragmentViewModel class 的实例,但提供者对预期参数一无所知。

Here is a post 关于那个主题。

如何解决这个问题?

  1. 如果可能,删除所有主构造函数参数。这应该是最简单的方法;
  2. 创建 ViewModelProvider.Factory 来处理视图模型的创建。

第一个选项很明确,但对于第二个选项,您应该执行以下操作。

创建 ViewModelProvider.Factory:

class BooksFragmentViewModelFactory (val context: Context) :
    ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(BooksFragmentViewModel::class.java)) {
            return BooksFragmentViewModel(context) as T
        } else {
            throw RuntimeException("Failed to create instance of the ${modelClass.simpleName}")
        }
    }
}

将工厂与 ViewModelProvider 一起使用:

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val bookViewModelFactory = BooksFragmentViewModelFactory(requireContext())
        booksModel = ViewModelProvider(requireActivity(), bookViewModelFactory).get(BooksFragmentViewModel::class.java)
        booksLoading_progressBar.visibility = View.VISIBLE
    }

有关更多说明,请查看此 codelab from Google (step 8)。有足够的示例来了解如何使用视图模型工厂的基础知识。