我正在尝试从SQLite数据库中读取数据,以便CursorAdapter可以将其格式化为我的列表视图项,但是当我尝试使用rawQuery时我收到错误,说我试图重新打开已经封闭的对象。我已经研究过这个错误,这个错误主要发生在人们在关闭游标后尝试使用他们的游标对象时,但我的游标关闭是在方法结束时,每次调用都会创建一个新的数据库。 close()方法已被删除,但无济于事。我已经包括了相关的课程。
MainActivityFragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Primary View Inflator
final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//Databse instatiation
final MySQLiteHelper mDbHelper = new MySQLiteHelper(getActivity());
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if((noteTitle.getText().toString().trim()).equals("")){
Toast.makeText(getActivity().getBaseContext(), "No Title Specified", Toast.LENGTH_SHORT).show();
}else {
String noteTitleString = noteTitle.getText().toString();
String noteBodyString = noteBody.getText().toString();
Toast.makeText(getActivity().getBaseContext(), "Added: " + noteTitleString, Toast.LENGTH_SHORT).show();
//Clear text fields and hide keyboard
noteTitle.getText().clear();
noteBody.getText().clear();
final InputMethodManager imm = (InputMethodManager)
getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
//Write new row into database and refresh listview
addNotes(mDbHelper, noteTitleString, noteBodyString);
readNotes(rootView);
}
}
});
}
private void addNotes(MySQLiteHelper mDbHelper, String title, String body){
// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(FeedEntry.COLUMN_NAME_TITLE, title);
values.put(FeedEntry.COLUMN_NAME_BODY, body);
// Insert the new row, returning the primary key value of the new row
db.insert(
FeedEntry.TABLE_NAME,
null,
values);
// db.close();
}
private void readNotes(View rootView){
MySQLiteHelper mDbHelper = new MySQLiteHelper(getActivity());
SQLiteDatabase db = mDbHelper.getWritableDatabase(); //changed from readable
// Query for items from the database and get a cursor back
Cursor notesCursor = db.rawQuery("SELECT * FROM notes", null);
// Find ListView to populate
ListView notelv = (ListView) rootView.findViewById(R.id.note_list_view);
// Setup cursor adapter using cursor from last step
final NotesListAdapter noteAdapter = new NotesListAdapter(rootView.getContext(), notesCursor, 0);
//// Attach cursor adapter to the ListView
notelv.setAdapter(noteAdapter);
notesCursor.close();
}
MySQLiteHelper
public class MySQLiteHelper extends SQLiteOpenHelper {
private static final String TEXT_TYPE = " TEXT";
private static final String INT_TYPE = " INTEGER";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
FeedEntry._ID + " INTEGER PRIMARY KEY," +
FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
FeedEntry.COLUMN_NAME_BODY + TEXT_TYPE +
" )";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + FeedEntry.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 = "FeedReader.db";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
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);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
错误堆栈
Process: com.example.ggould.scribble, PID: 8408
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT * FROM notes
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:152)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
at android.widget.CursorAdapter.getView(CursorAdapter.java:245)
at android.widget.AbsListView.obtainView(AbsListView.java:2344)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
at android.widget.ListView.onMeasure(ListView.java:1182)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:393)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17430)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
at android.view.View.measure(View.java:17430)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
答案 0 :(得分:0)
我实际上最终会发现任何遇到此问题的人。
我从readNotes()方法中删除了这一行,因为它实际上创建了与数据库的第二个连接,并且当一个接一个地调用add和read方法时,数据库将只识别第一个请求并完全删除另一个连接。然后我传入mDbHelper作为参数。
MySQLiteHelper mDbHelper = new MySQLiteHelper(getActivity());
我还必须删除此行,因为光标在CursorAdapter完成其进程之前关闭,从而引发错误。
notesCursor.close();