Android 查看没有创建:没有这样的方法错误

Android view no creating: No Such Method Error

我的应用中有关注者

自定义应用程序class:

class MyApplication: Application(){
  .....
  .....
}

具有通用实现的 BaseViewModel:

class BaseViewModel(application:MyApplication):AndroidViewModel(application) {
   ........
}

扩展 BaseViewModel 的 ViewModel:

class DataViewModel(application:MyApplication):BaseViewModel(application) {
  ......
}

我正在尝试获取片段中的 ViewModel 实例

private val viewModel by lazy {
    ViewModelProviders.of(this).get(DataViewModel::class.java)
}

但是应用程序崩溃并出现以下异常:

Unable to start activity ComponentInfo{com.test/com.test.activity.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.test.category.DataViewModel
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
 Caused by: java.lang.RuntimeException: Cannot create an instance of class com.test.category.DataViewModel
    at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:232)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
    at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
    at com.test.fragments.CategoriesFragment.onViewCreated(CategoriesFragment.kt:38)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:892)
    at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
    at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
    at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
    at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
    at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
    at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
    at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
    at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333)
    at android.app.Activity.performStart(Activity.java:6992)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
    at android.os.Handler.dispatchMessage(Handler.java:105) 
    at android.os.Looper.loop(Looper.java:164) 
    at android.app.ActivityThread.main(ActivityThread.java:6541) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
 Caused by: java.lang.NoSuchMethodException: <init> [class android.app.Application]
    at java.lang.Class.getConstructor0(Class.java:2320)
    at java.lang.Class.getConstructor(Class.java:1725)
    at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:230)

早些时候我的 BaseViewModel 正在扩展ViewModel。后来我不得不更改它 AndroidViewModel 因为我在我的项目中使用 Room 并且对于数据库初始化它需要上下文。

试试这个方法:

   lateinit var viewModel: DataViewModel

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)


    viewModel = activity?.run {
        ViewModelProvider(this).get(DataViewModel::class.java)
    }?: throw Exception("Invalid Activity")

您必须创建自定义 ViewModelProvider.Factory 才能实现参数化 ViewModel。检查以下内容:

  • 在Java中:
public class MyViewModelFactory implements ViewModelProvider.Factory {
    private MyApplication mApplication;


    public MyViewModelFactory(MyApplication application) {
        mApplication = application;
    }


    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {

        if(modelClass == DataViewModel.class)
            return (T) new DataViewModel(mApplication);

        throw new IllegalArgumentException("Unknown ViewModel class");
    }
}
  • 在 Kotlin 中:
class MyViewModelFactory(private val mApplication: MyApplication) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return when(modelClass) {
            DataViewModel::class.java -> DataViewModel(mApplication) 

            else -> throw IllegalArgumentException("Unknown ViewModel class")
        } as T
    }
}

现在启动您的 ViewModel,如下所示:

  • 在Java中:
DataViewModel dataViewModel = ViewModelProviders
    .of(this, new MyViewModelFactory(this.getApplication()))
    .get(DataViewModel.class);
  • 在 Kotlin 中:
val dataViewModel = ViewModelProviders
    .of(this, MyViewModelFactory(this.application))
    .get(DataViewModel::class.java)