我在DAO文件中返回查询时遇到问题。我想在MainActivity中存储一个变量,用于插入的最后一个ID:
int lastId = taskViewModel.getLastID();
在DAO中,我有以下查询:
@Query ("SELECT MAX(id) FROM task_table")
int getLastID();
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;
}
}
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;
}
}
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)
我认为查询的返回类型或者我读取返回类型的方式有问题。有人能帮帮我吗?事先谢谢你
一小步
使用LiveData,我实际上可以看到我插入的任务ID是什么,但我不能在onChange方法之外使用它。我需要这个id,因为我想创建一个id==到任务id的通知。我该怎么做呢?
MainActivity、TaskViewModel、TaskRepository、TaskDao
您的错误是因为您正在将dao访问到主线程“导致:java.lang.IllegalStateException:无法访问主线程上的数据库,因为它可能会在很长一段时间内锁定UI。”
更改为在后台任务或livedata中运行
在后台运行任务示例
public class TaskRepository {
private TaskDao taskDao;
private int lastID;
public TaskRepository(Application application) {
TaskDatabase database = TaskDatabase.getInstance(application);
taskDao = database.taskDao();
//run in backgroung task
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
lastID = repository.getLastID();
}
});
}
public int getLastID() {
return lastID;
}
}
@Query ("SELECT MAX(id) FROM task_table")
LiveData<int> getLastID();
public class TaskViewModel extends AndroidViewModel {
private TaskRepository repository;
private int lastID;
public TaskViewModel(@NonNull Application application) {
super(application);
repository = new TaskRepository(application);
}
public LiveData<int> getLastID() {
return taskDao.getLastID();
}
}
public class TaskRepository {
private TaskDao taskDao;
private int lastID;
public TaskRepository(Application application) {
TaskDatabase database = TaskDatabase.getInstance(application);
taskDao = database.taskDao();
}
public LiveData<int> getLastID() {
return taskDao.getLastID();
}
}
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
TaskViewModel viewmodel = new TaskViewModel(getApplicationContext())
dao.getLastID().observe(this, new Observer<int>() {
@Override
public void onChanged(int value) {
}
});
}
}
//unico metodo obbligatorio
@Override
protected Void doInBackground(Task... tasks) {
taskDao.insert(tasks[0]);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (onResultListener != null) {
onResultListener.onResult();
}
}
interface ResultListener{
public void onResult();
}
}
使用calback调用
taskViewModel.insert(new TaskRepository.InsertTaskAsyncTask.ResultListener(){
@Override
public void onResult() {
Task task = new Task(title, data_calendario, time, priority, type, note, "pending");
taskViewModel.insert(new TaskRepository.InsertTaskAsyncTask.ResultListener(){
@Override
public void onResult() {
taskViewModel.getLastID().observe(MainActivity.this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
System.out.println("Test ID: "+integer);
}
});
}
}, task);
问题内容: 基本上,我想要Android中的EditText,可以在其中输入一个整数值。也许有比EditText更合适的对象了吗? 问题答案: 现在,使用。使用强制它是数字。将结果字符串转换为整数(例如)。 将来,您可能会考虑使用可用的小部件(计划在Honeycomb中使用)。
问题内容: 一个简单的问题:如何返回MySQL表的字段类型。我知道还是但是我只想返回那个单个参数。例如: 问题答案: 您可以使用 这将以以下格式返回结果
问题内容: 以下查询应返回从动漫中扮演角色的人物的姓名。但我收到以下错误: Blockquote ORA-01427:单行子查询返回多个行 提前致谢! 问题答案: 代替 使用 查询中有5个条件需要更改。 UPD 另外,您的查询等同于
问题内容: 我正在尝试获取少量数据,在Excel中包含大约200个字段,并从SQL中检索数据,其中每个项目的where子句中都包含该字段。 我希望能够在excel中进行检索(希望本身无需编写任何其他代码-可能是简单的Excel ODBC或带有查询的SQL连接。因此,我的数据最终将在Excel文档中显示: 我不确定我是否足够清楚地说明自己…。 我使用的是Excel 2007,而我在其他地方也有201
问题内容: 我想知道以下内容: 如何从数据库中的多个表中获取数据? 有哪些类型的方法可以做到这一点? 什么是联接和工会,它们之间有何不同? 什么时候应该使用每个与其他比较? 我打算在我的应用程序(例如,PHP)中使用此功能,但是不想对数据库运行多个查询,我需要在单个查询中从多个表中获取数据的哪些选项? 注意:我正在写这篇文章是因为我希望能够链接到有关我在PHP队列中不断遇到的众多问题的书面指南,因
问题内容: 桌子: 我的查询: 我收到“ MySQL子查询返回多个行”错误。 我知道此查询可以使用以下查询的解决方法: 然后使用php循环遍历结果并执行以下查询以获取和回显它: 但是我认为可能会有更好的解决方案? 问题答案: 简单的解决方法是在子查询中添加一个子句: 一个更好的选择(就性能而言)是使用联接: