我只是想学习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)
我试图在Internet上寻找解决方案,但没有成功。 stackOverflow上可用的解决方案要求将构造函数公开给viewModel,而我的构造函数已经是该模型。
这是我的viewModel:
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();
}
我不知道我在做什么错
答案 0 :(得分:0)
正如它在靠近底部的调用堆栈中所说的那样,您正在主线程上调用数据库查询。
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和ViewModels,只需使用LiveData
。最终产品也将更容易使用。
答案 1 :(得分:0)
我刚刚找到了解决问题的方法。
用于创建viewModel类的新实例的ViewModelProvider始终调用默认构造函数。因为在我的应用程序中,我没有声明默认构造函数,所以它会向我抛出错误“ 无法创建类ViewModel的实例”。因此,您必须在ViewModel类中创建一个默认构造函数。
如果您不想创建默认的构造函数或想要像我一样创建其他构造函数,则必须创建一个视图模型提供程序工厂。
Here,您可以提供一个示例如何为viewModel创建工厂类。
希望此解决方案可以帮助您更好地理解ViewModel。
答案 2 :(得分:0)
问题是您正在尝试在主线程上运行查询。 您可以通过两种方式解决此问题:
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;
}