I have a problem with the return of a query in the DAO file. I want to store in the MainActivity a variable for the last ID inserted:
int lastId = taskViewModel.getLastID();
In the DAO I have the following query:
@Query ("SELECT MAX(id) FROM task_table")
int getLastID();
In the ViewModel I have:
public class TaskViewModel extends AndroidViewModel {
private TaskRepository repository;
private int lastID;
public TaskViewModel(@NonNull Application application) {
super(application);
repository = new TaskRepository(application);
lastID = repository.getLastID();
}
public int getLastID(){
return lastID;
}
}
And in the Repository I have:
public class TaskRepository {
private TaskDao taskDao;
private int lastID;
public TaskRepository(Application application) {
TaskDatabase database = TaskDatabase.getInstance(application);
taskDao = database.taskDao();
lastID = taskDao.getLastID();
}
public int getLastID() {
return lastID;
}
}
So, the query should return a single int Id from the table, but I occur in an error when I run the app as you can se below:
2019-12-03 15:37:51.096 19684-19684/com.example.todoapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.todoapp, PID: 19684
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.todoapp/com.example.todoapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.todoapp.TaskViewModel
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.example.todoapp.TaskViewModel
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:238)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
at com.example.todoapp.MainActivity.onCreate(MainActivity.java:60)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
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.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:230)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
at com.example.todoapp.MainActivity.onCreate(MainActivity.java:60)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
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.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267)
at androidx.room.RoomDatabase.query(RoomDatabase.java:323)
at androidx.room.util.DBUtil.query(DBUtil.java:83)
at com.example.todoapp.TaskDao_Impl.getLastID(TaskDao_Impl.java:1794)
at com.example.todoapp.TaskRepository.<init>(TaskRepository.java:94)
at com.example.todoapp.TaskViewModel.<init>(TaskViewModel.java:59)
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:230)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:164)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:130)
at com.example.todoapp.MainActivity.onCreate(MainActivity.java:60)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
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)
I think there is something wrong in the return type of the query or how I read the return type. Someone can help me please? Thank you in advance
A LITTLE STEP
With the LiveData I can actually see what is the task's ID that I inserted but i can not use it outside the method onChange. I need this id because I want to create a notification with id == to the id of the task. How can I do it?
UPDATE AND QUESTION If I set a variable like this in the main activity: 'private int lastID;' and I use it inside the onChange method (using the LiveData mode), it can't be used outside the method because I get the error "NullPointException"(see the answer below). I really need a way to simply save the id of the inserted Task and than use it for create the Notification. I don't know how to do.....
HERE THERE ARE MY MAIN FILES