活动代码:
public class ShowRawDB extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_raw_db);
displayDatabaseInfo();
}
private void displayDatabaseInfo() {
DatabaseHelper DBHelper = new DatabaseHelper(this);
SQLiteDatabase db = DBHelper.getReadableDatabase();
String[] projection = {
DBHelper.COL_ID,
DBHelper.COL_DATE,
DBHelper.COL_PUNCHIN
};
String sortOrder =
DBHelper.COL_DATE + " DESC";
Cursor cursor = db.query(
DBHelper.TABLE_NAME, // The table to query
projection, // The columns to return
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
ListView lst = (ListView) findViewById(R.id.listDB);
DBAdapter MyAdapter = new DBAdapter(this, cursor);
lst.setAdapter(MyAdapter);
MyAdapter.changeCursor(cursor);
cursor.close();
}
}
我的游标适配器:
public class DBAdapter extends CursorAdapter {
public DBAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
return LayoutInflater.from(context).inflate(R.layout.item_punchlist, viewGroup, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView txtDate = (TextView) view.findViewById(R.id.itemNum);
TextView txtItemID = (TextView) view.findViewById(R.id.itemDate);
// Extract properties from cursor
String itemDate = cursor.getString(cursor.getColumnIndexOrThrow("DBHelper.COL_DATE"));
int itemID = cursor.getInt(cursor.getColumnIndexOrThrow("DBHelper.COL_ID"));
// Populate fields with extracted properties
txtDate.setText(itemDate);
txtItemID.setText(String.valueOf(itemID));
}
}
数据库助手:
package su.joel.punchintime;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public final class DatabaseHelper extends SQLiteOpenHelper {
public static final String TABLE_NAME = "punchlog";
public static final String COL_ID = "_id";
public static final String COL_DATE = "date";
public static final String COL_PUNCHIN = "punchin";
public static final String COL_PUNCHOUT = "punchout";
public static final String COL_ONDUTY = "onduty";
public static final String COL_FORGOTIN = "forgotin";
public static final String COL_FORGOTOUT = "forgotout";
public static final String COL_LATEIN = "latein";
public static final String COL_LATEOUT = "lateout";
String SQL_CREATE_ENTRIES =
"CREATE TABLE " + TABLE_NAME + " (" +
COL_ID + " INTEGER PRIMARY KEY," +
COL_DATE + " TEXT," +
COL_PUNCHIN + " TEXT," +
COL_PUNCHOUT + " TEXT," +
COL_ONDUTY + " INTEGER," +
COL_FORGOTIN + " INTEGER," +
COL_FORGOTOUT + " INTEGER," +
COL_LATEIN + " INTEGER," +
COL_LATEOUT + " INTEGER);";
String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + TABLE_NAME;
// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "PunchInTime.db";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// This database is only a cache for online data, so its upgrade policy is
// to simply to discard the data and start over
db.execSQL(SQL_DELETE_ENTRIES);
System.out.println(SQL_CREATE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
为什么我会这样?在传递给Cursor之前,我似乎没有关闭数据库。
logcat的:
07-06 03:29:18.270 7848-7848/su.joel.punchintime E/AndroidRuntime: FATAL EXCEPTION: main
Process: su.joel.punchintime, PID: 7848
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, date, punchin FROM punchlog ORDER BY date DESC
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:151)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:123)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:236)
at android.widget.CursorAdapter.getView(CursorAdapter.java:280)
at android.widget.AbsListView.obtainView(AbsListView.java:2379)
at android.widget.ListView.makeAndAddView(ListView.java:1970)
at android.widget.ListView.fillDown(ListView.java:704)
at android.widget.ListView.fillFromTop(ListView.java:765)
at android.widget.ListView.layoutChildren(ListView.java:1744)
at android.widget.AbsListView.onLayout(AbsListView.java:2171)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.support.constraint.ConstraintLayout.onLayout(ConstraintLayout.java:1197)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:434)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:726)
at android.view.View.layout(View.java:17745)
at android.view.ViewGroup.layout(ViewGroup.java:5579)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2380)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2094)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1280)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6432)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6355)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
答案 0 :(得分:0)
CursorAdapter
取得传入的Cursor
的所有权。自行调用close()
会导致此错误。从此处删除cursor.close()
:
MyAdapter.changeCursor(cursor);
cursor.close();