Android Cursor Problem - android

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)

Related

How to free up cursor after this in following code?

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.

cannot find whats causing Finalizing a Cursor that has not been deactivated or closed

I can't find what causing this error in my database, I posted some question before related to this issue but since the code is quite long i remove some of them that has the same
declaration because stackoverflow won't allow me to post more than 3000 characters. i tried using this method to close the cursor, but somehow it doesn't fix the problem.
public Cursor getMove(){
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME};
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE1, columns, null, null, null, null, null);
} finally {
if(c != null){
c.close();
}
}
return c;
}
Anyway [here's] the whole class I hope someone can help me.
Closing the cursor is the reason why I'm getting this error so instead of this:
public Cursor getMove(){
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME};
Cursor c = null;
try {
c = ourDatabase.query(DATABASE_TABLE1, columns, null, null, null, null, null);
} finally {
if(c != null){
c.close();
}
}
return c;
}
I just used this line of code:
public Cursor getMove(){
String[] columns = new String[]{KEY_ID1, KEY_MOVENAME};
Cursor c = null;
c = ourDatabase.query(DATABASE_TABLE1, columns, null, null, null, null, null);
return c;
}
The reason may be that you are using multiple instances of your DB connections and not closing all cursors that you hand out. The answer that you accepted (your own) could be dangerous. Are you releasing the cursors that you hand out from this method ? You will end up taking precious resources on the phone that will never be released if you don't.
You can solve this by maintaining one database instance (by using a singleton to handle the DB connections) and closing all cursors eventually. Either marshal them into POJOs and close the cursors immediately or send back a cursor and manage it with a call to a method like activity.managedQuery(). You might also want to look at android's SQL lite locking mechanism.

What is The use of moveToFirst () in SQLite Cursors

I am a programming newbie
and I found this piece of code in the internet and it works fine
Cursor c=db.query(DataBase.TB_NAME, new String[] {DataBase.KEY_ROWID,DataBase.KEY_RATE}, DataBase.KEY_ROWID+"= 1", null, null, null, null);
if(c!=null)
{
c.moveToFirst();
}
but I am not able to understand the use of the
if(c!=null)
{
c.moveToFirst();
}
part. What does it do exactly , and if I remove the
if(c!=null) { c.moveToFirst(); }
part, the code doesn't work.
The docs for SQLiteDatabase.query() say that the query methods return:
"A Cursor object, which is positioned before the first entry."
Calling moveToFirst() does two things: it allows you to test whether the query returned an empty set (by testing the return value) and it moves the cursor to the first result (when the set is not empty). Note that to guard against an empty return set, the code you posted should be testing the return value (which it is not doing).
Unlike the call to moveToFirst(), the test for if(c!=null) is useless; query() will either return a Cursor object or it will throw an exception. It will never return null.
if (c.moveToFirst()) {
while(!c.isAfterLast()) { // If you use c.moveToNext() here, you will bypass the first row, which is WRONG
...
c.moveToNext();
}
}
Cursor is not a Row of the result of query. Cursor is an object that can iterate on the result rows of your query. Cursor can moves to each row. .moveToFirst() method move it to the first row of result table.
moveToFirst() method moves the cursor to the first row. It allows to perform a test whether the query returned an empty set or not. Here is a sample of its implementation,
if (cursor.getCount() == 0 || !cursor.moveToFirst()) {
return cursor.getLong(cursor.getColumnIndexOrThrow(ID_COLUMN));
cursor.close();
what macio.Jun says is right!
we have code like below:
String sql = "select id,title,url,singer,view,info from cache where id=" + id;
SQLiteDatabase db = getMaintainer().getReadableDatabase();
Cursor query = db.rawQuery(sql, null);
query.moveToFirst();
while(query.moveToNext()){
DBMusicData entity = new DBMusicData();
entity.setId(query.getString(query.getColumnIndex(FIELD_ID)));
entity.setTitle(query.getString(query.getColumnIndex(FIELD_TITLE)));
entity.setSinger(query.getString(query.getColumnIndex(FIELD_SINGER)));
entity.setTitlepic(query.getString(query.getColumnIndex(FIELD_PICURL)));
entity.setInfoUrl(query.getString(query.getColumnIndex(FIELD_INFO)));
entity.setViews(query.getString(query.getColumnIndex(FIELD_VIEW)));
Log.w(tag, "cache:"+ entity.toString());
}
query.close();
query=null;
db.close();
db=null;
If we have only one record in the cache table, query.moveToFirst(); will cause that no record returns.

Cursor Index Out of Bounds Exception

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

Querying a content provider that has no records?

I am working on a method that queries a content provider using a cursor. After I delete a record, it calls the loadfromProvider method and refreshes the arraylist. The content provider normally has records in it however, when I delete all the records and the query runs automatically it throws exceptions. Here is my method:
private void loadFromProvider() {
// Clear the existing array list
EQlist.clear();
ContentResolver cr = getContentResolver();
// Return all the saved records
Cursor c = cr.query(EQProvider.CONTENT_URI, null, null, null, null);
if (c.moveToFirst()) {
do {
String details = c.getString(EQProvider.DETAILS_COLUMN);
String linkString = c.getString(EQProvider.LINK_COLUMN);
EQli q = new EQli(details, linkString);
addEQToArray(q);
} while(c.moveToNext());
}
c.close();
}
When I run this with no records in the content provider it throws the following:
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
I think this is due to the cursor trying to parse a null value. I am trying to figure out a way that if the cursor does not come back with any records, it bypasses the rest of the code and does nothing happens.
Any help would be appreciated. Thanks
If there are no records your cursor should be empty. If the cursor is empty then c.moveToFirst() will return false and you are not going to enter the do-while loop.
Debug your application and make sure that the cursor is empty.

Categories

Resources