【问题标题】:Error in creating instance of a class viewModel创建类 viewModel 的实例时出错
【发布时间】:2018-06-20 06:59:36
【问题描述】:

我只是想学习 Room。因此,我使用 Google 在this 中提供的指南创建了一个示例应用程序。我收到以下错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.brahma/com.brahma.ui.SignUpActivity}: java.lang.RuntimeException: Cannot create an instance of class com.brahma.viewModel.UserViewModel
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6501)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.RuntimeException: Cannot create an instance of class com.brahma.viewModel.UserViewModel
        at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:207)
        at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134)
        at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102)
        at com.brahma.ui.SignUpActivity.onCreate(SignUpActivity.java:72)
        at android.app.Activity.performCreate(Activity.java:7036)
        at android.app.Activity.performCreate(Activity.java:7027)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6501) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:199)
        at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134) 
        at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102) 
        at com.brahma.ui.SignUpActivity.onCreate(SignUpActivity.java:72) 
        at android.app.Activity.performCreate(Activity.java:7036) 
        at android.app.Activity.performCreate(Activity.java:7027) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6501) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 
     Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
        at android.arch.persistence.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:164)
        at android.arch.persistence.room.RoomDatabase.query(RoomDatabase.java:192)
        at com.brahma.Room.UserDao_Impl.getUser(UserDao_Impl.java:56)
        at com.brahma.repository.UserRepository.<init>(UserRepository.java:18)
        at com.brahma.viewModel.UserViewModel.<init>(UserViewModel.java:17)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334) 
        at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:199) 
        at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134) 
        at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102) 
        at com.brahma.ui.SignUpActivity.onCreate(SignUpActivity.java:72) 
        at android.app.Activity.performCreate(Activity.java:7036) 
        at android.app.Activity.performCreate(Activity.java:7027) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1215) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6501) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

我试图在互联网上寻找解决方案,但没有成功。 stackOverflow 上提供的解决方案要求将 viewModel 的构造函数公开,我的 costructor 已经是。

这是我的视图模型:

public class UserViewModel extends AndroidViewModel{

    private UserRepository mUserRepository;
    private User mUserInfo;

    public UserViewModel( Application application) {
        super(application);
        mUserRepository = new UserRepository(application);
        mUserInfo = mUserRepository.getmUserInfo();
    }


    public User getUserInfo(){
        return mUserInfo;
    }
    public void insert(User user){
        mUserRepository.insert(user);
    }
}

下面是我实例化 viewModel 的活动:

protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FacebookSdk.sdkInitialize(getApplicationContext());
        setContentView(R.layout.activity_sign_up);
        AppEventsLogger.activateApp(this, getString(R.string.facebook_app_id));
        initViews();

        mUserViewModel = ViewModelProviders.of(this).get(UserViewModel.class);

        callbackManager = CallbackManager.Factory.create();
        mGoogleSignUp.setOnClickListener(this);
        mFacebookSignUp.setOnClickListener(this);
        initGoogleApiClient();
    }

我不知道我做错了什么。

【问题讨论】:

    标签: android android-room android-viewmodel


    【解决方案1】:

    正如它在靠近底部的调用堆栈中所说,您正在主线程上调用数据库查询。

     Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
    

    使用 Room,您无法在 UI 线程上发出请求,我相信这是因为这条线。

    mUserInfo = mUserRepository.getmUserInfo();
    

    如果您使用的是 Room 和 ViewModel,只需使用 LiveData。最终产品也将更容易使用。

    【讨论】:

    • 我认为不是因为我只是尝试扩展 viewModel 而不是 AndroidViewModel 并且与数据库相关的错误消失了。但是创建 viewModel 实例的主要问题仍然存在
    • 您是否尝试过从 ViewModel 中删除数据库逻辑并运行它?
    【解决方案2】:

    我刚刚找到了解决问题的方法。

    用于创建 viewModel 类的新实例的 ViewModelProvider 总是调用默认构造函数。由于在我的应用程序中我没有声明默认构造函数,这就是为什么它向我抛出错误“无法创建类 ViewModel 的实例”。所以你必须在你的 ViewModel 类中创建一个默认构造函数。

    如果您不想创建默认构造函数或想创建不同的构造函数,就像我的情况一样,您必须创建一个视图模型提供程序工厂。

    Here 您可以提供一个示例,如何为您的 viewModel 创建一个工厂类。

    希望这个解决方案能帮助您更好地理解 ViewModel。

    【讨论】:

      【解决方案3】:

      问题是您试图在主线程上运行查询。 您可以通过两种方式解决此问题:

      1.在您的存储库类中,使用 mUserRepository.getmUserInfo() 中的 Asynctask,同时在您的情况下获取类型列表或用户类型的数据。会解决你的问题。

      2.致电allowMainThreadQueries() 将解决此问题。 您需要像这样在 RoomDatabase 实例中调用 allowMainThreadQueries():

      //where INSTANCE is of type Database
          public static Database getDatabase(final Context context) {
              if (INSTANCE == null) {
                  synchronized (Database.class) {
                      if (INSTANCE == null) {
                          INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                                  Database.class, DATABASE_NAME)
                                  // Wipes and rebuilds instead of migrating if no Migration object.
                                  // Migration is not part of this codelab.
                                  .fallbackToDestructiveMigration()
                                  //allows queries to execute on main thread
                                  .allowMainThreadQueries()
                                  //.addCallback(sRoomDatabaseCallback)
                                  .build();
      
                      }
                  }
              }
              return INSTANCE;
          }
      

      【讨论】:

        猜你喜欢
        • 2013-08-27
        • 2021-11-28
        • 2017-12-13
        • 1970-01-01
        • 2018-11-02
        • 1970-01-01
        相关资源
        最近更新 更多