Android: 确保 Cursor 在访问数据之前正确初始化
Android: Make sure the Cursor is initialized correctly before accessing data from it
我正在尝试构建一个 Android 待办事项列表应用程序,它使用 SQL 数据库来保存用户输入(标题、任务、日期、时间)。在我使用 2 个活动(MainActivity、Dialog)的项目中,我使用的代码使用 onClick(Add_task) 成功保存了用户输入,但是当我使用多个 Cursor 更新列表视图时 UI 它给出了以下错误。
Logcat
08-08 13:42:15.540 6051-6051/com.naive.LISTY E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.naive.LISTY, PID: 6051
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:289)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at listy.naive.com.listy.MainActivity.updateUI(MainActivity.java:102)
at listy.naive.com.listy.Dialog.Add_task(Dialog.java:58)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
更新UI
更新UI
public void updateUI() {
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor title_cursor = db.query(TaskContract.TaskEntry.TABLE, // Cursor Title
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TITLE},
null, null, null, null, null);
Cursor time_cursor = db.query(TaskContract.TaskEntry.TABLE, // Cursor Title
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TIME},
null, null, null, null, null);
while (title_cursor.moveToNext()) {
int idx = title_cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(title_cursor.getString(idx));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
R.layout.item_todo,
R.id.task_title,
taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
while (time_cursor.moveToNext()) {
int idx = time_cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(time_cursor.getString(idx));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
R.layout.item_todo,
R.id.task_time,
taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
time_cursor.close();
title_cursor.close();
db.close();
}
尝试在访问前将光标移动到第一行:
Cursor time_cursor = db.query(TaskContract.TaskEntry.TABLE, // Cursor Title
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TIME},
null, null, null, null, null);
if(time_cursor != null){
time_cursor.moveToFirst(); // this is part of cursor initialization
while (title_cursor.moveToNext()) {
int idx = title_cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(title_cursor.getString(idx));
}
}
我正在尝试构建一个 Android 待办事项列表应用程序,它使用 SQL 数据库来保存用户输入(标题、任务、日期、时间)。在我使用 2 个活动(MainActivity、Dialog)的项目中,我使用的代码使用 onClick(Add_task) 成功保存了用户输入,但是当我使用多个 Cursor 更新列表视图时 UI 它给出了以下错误。
Logcat
08-08 13:42:15.540 6051-6051/com.naive.LISTY E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.naive.LISTY, PID: 6051
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:289)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at listy.naive.com.listy.MainActivity.updateUI(MainActivity.java:102)
at listy.naive.com.listy.Dialog.Add_task(Dialog.java:58)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
更新UI
更新UI
public void updateUI() {
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor title_cursor = db.query(TaskContract.TaskEntry.TABLE, // Cursor Title
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TITLE},
null, null, null, null, null);
Cursor time_cursor = db.query(TaskContract.TaskEntry.TABLE, // Cursor Title
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TIME},
null, null, null, null, null);
while (title_cursor.moveToNext()) {
int idx = title_cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(title_cursor.getString(idx));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
R.layout.item_todo,
R.id.task_title,
taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
while (time_cursor.moveToNext()) {
int idx = time_cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(time_cursor.getString(idx));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
R.layout.item_todo,
R.id.task_time,
taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
time_cursor.close();
title_cursor.close();
db.close();
}
尝试在访问前将光标移动到第一行:
Cursor time_cursor = db.query(TaskContract.TaskEntry.TABLE, // Cursor Title
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TIME},
null, null, null, null, null);
if(time_cursor != null){
time_cursor.moveToFirst(); // this is part of cursor initialization
while (title_cursor.moveToNext()) {
int idx = title_cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(title_cursor.getString(idx));
}
}