SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {
HistoryEntry._ID,
HistoryEntry.COLUMN_HISTORY_INPUT,
HistoryEntry.COLUMN_HISTORY_RESULT
};
Cursor cursor = db.query(HistoryEntry.TABLE_NAME,
projection,
null,
null,
null,
null,
null);
ListView historyListView = (ListView) findViewById(R.id.list);
mCursorAdaptor = new HistoryCursorAdaptor(this, cursor);
historyListView.setAdapter(mCursorAdaptor);
//the code is using to read data from database but error in query. says ," free up cursor after use."
you need to call cursor.close() to release the cursor and its resources but as per your code, once we close the cursor then your adapter won't be able to access it, so the idle place will be to close the cursor inside onDestroy method of activity life cycle and for that, you can declare cursor as global variable (outside current method)
Assuming HistoryCursorAdaptor is a CursorAdapter, it takes ownership of the passed in Cursor and you should not be closing it yourself.
If you want to explicitly close the cursor owned by a cursor adapter, you can call changeCursor(null) on the adapter.
Related
with simple below code i get this error for close database or cursor:
Database﹕ close() was never explicitly called on database '/data/data/ir.tsms/databases/tsms'
android.database.sqlite.DatabaseObjectNotClosedException:
My Function:
public Boolean searchLastID( Long lastID){
SQLiteDatabase db = this.getReadableDatabase();
String selectQuery = "SELECT * FROM " + this.RECEIVE_FIELDS_TABLE + " WHERE lastId = ?" ;
String[] args = {String.valueOf(lastID)};
Cursor cursor = db.rawQuery(selectQuery, args);
//db.close();
return cursor.moveToFirst();
}
after uncommenting db.close();
Cursor﹕ Finalizing a Cursor that has not been deactivated or closed. database = /data/data/ir.tsms/databases/tsms, table = null, query = SELECT * FROM ReceiveFields WHERE lastId = ?
whats problem and how to resolve that? i can't find any document about this problem. Thanks
make your cursor a global variable
and inside your onDestory Method close your cursor and your database
#Override
protected void onDestroy() {
super.onDestroy();
cursor.close();
db.close();
}
As soon as you're done retrieving the data of your query from your database you should close the Cursor or at least deactivate it. (Keyword: Freeing resources)
Following two quotes from the Docs on the close() and deactivate() method:
#close()
Closes the Cursor, releasing all of its resources and making it
completely invalid. Unlike deactivate() a call to requery() will not
make the Cursor valid again.
#deactivate()
Deactivates the Cursor, making all calls on it fail until requery() is
called. Inactive Cursors use fewer resources than active Cursors.
Calling requery() will make the cursor active again.
I understand that a after a database is closed, the cursor becomes "invalid", does that also close the cursor at the same time? Does that avoid having to do what is shown below?
example 1
public void String getResultsAndReturnString() {
String result = "";
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = qb.query(db, projection, null, null,
null, null, null);
cursor.close(); <-- explicit cursor close example one
db.close();
return result;
}
example 2
public void Cursor getResultsAndReturnCursor(){
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = qb.query(db, projection, null, null,
null, null, null);
return cursor;
}
public void closeOut(Cursor cursor, SQLiteDatabase dataBase){
cursor.close(); <-- explicit cursor close example two
dataBase.close();
}
The cursor isn't closed in the strict sense by closing the database (it's still there and you can perform operations on it), but as you know, closing the database makes the cursor useless. You should close cursors explicitly after you're done using them for a number of reasons:
1) As you noted, after closing the database, any remaining cursors become "invalid," and cannot be relied upon for accurate data;
2) You will see warnings in LogCat;
3) You risk memory leaks if you maintain a reference to a cursor; and
4) It's simply good programming practice to close out resources that you no longer need.
In attempting to execute a query on my database, I get this exception. However, the documentation states that the method SQLiteDatabase.query(...) returns, "A Cursor object, which is positioned before the first entry," which I interpret to mean that the Cursor is at the start of the rows returned. If I add the Cursor.moveToFirst() before accessing data in the Cursor, I get no exception. What is going on? Do I need to always call "moveToFirst" before trying to get data? The documentation says this method, "moves the cursor to the first row."
Cursor c = db.query(TABLENAME, null, null, null, null, null, null);
Log.d("TAG",""+c.getInt(c.getColumnIndex("_id")));
After query you need to call next() or moveToFirst(). Cursors are lazy loaded, after calling these methods cursor is loaded into memory. You can decide when to do it.
to iterate trough all rows:
Cursor c = db.query(TABLENAME, null, null, null, null, null, null);
while(c.moveToNext()) {
int id = c.getInt(c.getColumnIndex("_ID"));
}
or you can use other cursor functions, for example moveToPosition() to access row specified by id
more info: http://developer.android.com/reference/android/database/Cursor.html
So I'm trying to get the values from a SQLite database into a cursor, then pick a random value. I can read the cursor with getString() as I normally would in the method, but after it returns the cursor it doesn't work correctly. I don't know why..
Here's my method for getting the cursor from the database. It seems to work correctly.
public Cursor getRandomText(String Rating)
{
Cursor cursor = myDatabase.query("Elec0RandTexts", new String[] {"Message"}, "Rating=?",
new String[]{Rating}, null, null, null);
cursor.moveToFirst();
cursor.close();
return cursor;
}
Here's my code for reading the cursor after it's returned.
Cursor result = dbh.getRandomText(Rating);
result.moveToFirst();
int RandText = rand.nextInt(result.getCount());
result.moveToPosition(RandText);
Toast.makeText(getApplicationContext(), "" + result.getString(RandText), Toast.LENGTH_LONG).show();
result.close();
I'm probably making a stupid mistake and not realizing it, but I can't figure this out.
Thanks,
~Elec0
cursor.close(); // in getRandomText()
after that you cannot obtain any data from the cursor - it is closed. Remove this line.
You close() your Cursor before you return it. From where it is returned to, you are then attempting to call moveToFirst(). This cannot be done if the Cursor is closed.
In your getRandomText(String) method, you should return the meaningful data from your Cursor, rather than the Cursor object itself. That way, the method that created the Cursor can continue to close the Cursor as it should. (It should just happen at the end of the method)
I'm trying to load the contents of my SQLite table into a ListView using the following code.
myDbHelper = new DatabaseHelper(this);
Cursor cursor = getData();
CursorAdapter dataSource = new SimpleCursorAdapter(this, R.layout.menu_item, cursor, fields, null);
menuList.setAdapter(datasource); //My ListView
private Cursor getData() {
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor cursor = db.query(TABLE_NAME, FROM, null, null, null,null, ORDER_BY);
return cursor;
}
When I run the app it passes through this code and then throws an error. Am I using the correct technique for adding data to a ListView?
You need to give a little more information.
Where does it crash?
What is the error that it gives?
You are using adapt but you do not declare it or set it to anything in your code snippet - if it's null, then that will be a problem.
menuList.setAdapter(adapt); //My ListView
Take a look at my example code here for how I use ListViews with SQLite.