Не могли бы вы указать, что случилось с этим спокойствием кода. genresCursor содержит "Приложение не закрыло исключение курсора или объекта базы данных, которое было открыто здесь". Как я могу закрыть этот курсор после вставки? Благодарю.
UPD: Кажется, что не было никакой проблемы. Несмотря на то, что он содержит исключение, которое все еще возможно для извлечения данных. Я, должно быть, ошибался в своем реальном заявлении, и это исключение привело меня к выводу, что это была проблема. Спасибо всем за участие.
public class DatabaseCursorActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
HashMap<Integer, String> _dummy = new HashMap<Integer, String>();
OpenDatabaseHelper helper = new OpenDatabaseHelper(this);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(OpenDatabaseHelper.GENRES_ID_KEY, 1);
values.put(OpenDatabaseHelper.GENRES_TITLE_KEY, "Test");
db.insert(OpenDatabaseHelper.GENRES_TABLE_NAME, null, values);
db.close();
helper.close();
db = helper.getReadableDatabase();
Cursor genresCursor = db.query(OpenDatabaseHelper.GENRES_TABLE_NAME, new String[]{OpenDatabaseHelper.GENRES_ID_KEY, OpenDatabaseHelper.GENRES_TITLE_KEY }, null, null, null, null, null);
int i = genresCursor.getColumnCount();
genresCursor.moveToFirst();
}
public class OpenDatabaseHelper extends SQLiteOpenHelper {
public static final String GENRES_TABLE_NAME = "genres";
public static final String GENRES_ID_KEY = "id";
public static final String GENRES_TITLE_KEY = "title";
public OpenDatabaseHelper(Context context) {
super(context, "ttt.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + GENRES_TABLE_NAME + "( id integer primary key not null, title text);" );
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
Лучшей практикой работы с курсором и базой данных является то, что вы должны открыть ее и закрыть ее в том же блоке кода. Когда я использую, чтобы вставлять строки в базу данных, я использую ее, чтобы открыть ее при запуске, а затем вставить много столбцов и закрыть ее перед возвратом.
В API до Honeycomb вы не получите сообщение о журнале и проблемах с производительностью относительно закрытого курсора, но API до того, как Honeycomb имеет не закрытый детектор Cursor, который будет записывать сообщение о том, что курсор не закрыт.
Изменение: закрыть базу данных в пределах одного блока кода. Курсор может быть закрыт в соответствии с сценарием, но должен быть закрыт до Context Deletion.
Я не понимаю, почему вы вставляете этот код:
db = helper.getReadableDatabase();
Cursor genresCursor = db.query(OpenDatabaseHelper.GENRES_TABLE_NAME, new String[]{OpenDatabaseHelper.GENRES_ID_KEY, OpenDatabaseHelper.GENRES_TITLE_KEY }, null, null, null, null, null);
int i = genresCursor.getColumnCount();
genresCursor.moveToFirst();
Проблема в этой части кода. Если вы просто хотите закрыть курсор, тогда вызовите genresCursor.close()
. Но с точки зрения архитектуры я не понимаю, зачем нужен этот код.
Сначала вы открываете базу данных и после вставки вы закрываете базу данных, а затем снова открываете ее для чтения.
Первое, что вам не нужно закрывать и открывать снова. Вы можете выполнить всю свою операцию и закрыть ее, поскольку вы все еще в одном блоке кода.
После выполнения операции с вашим genresCursor закройте его genresCursor.close(), а затем закройте свой db.Надеюсь, что все будет хорошо.
SQLiteOpenHelper
прекратите закрыватьSQLiteOpenHelper
иSQLiteDatabase
- сделайте это вActivity#onDestroy()
или в чем-то подобном (т.Activity#onDestroy()
конце жизненного цикла вашей деятельности). Начните закрывать вашиCursor
или начните использоватьActivity#startManagingCursor