Cursor variable reuse - android

I'm using a cursor in a while loop to execute multiple queries on my database, so each time Content Resolver returns new cursor object instance. I am uncertain about proper way I should reuse the cursor during each iteration of the loop:
Close it once, after all operations being performed
Cursor c;
try {
while(condition) {
c = Context.getContentResolver().query(...);
// fetching values
}
} finally {
if (c != null) {
c.close()
}
}
Close it at the end of each iteration
Cursor c;
try {
while(condition) {
c = Context.getContentResolver().query(...);
// fetching values
if (c != null) {
c.close()
}
}
} finally {
if (c != null) {
c.close()
}
}
Create new cursor variable inside while loop
while(condition) {
Cursor c = Context.getContentResolver().query(...);
try {
// fetching values
} finally {
if (c != null) {
c.close()
}
}
}
?

Case 1 is bad since you're assigning a new cursor in your loop and you only get to close the last assigned cursor.
Case 2 and 3 are very similar but I prefer case 3 because with case 2 you can break out of your loop unexpectedly but with case 3 you keep the cursor in the loop scope and the loop can keep running.

In your examples the third variant is most useful because you open-close the same Cursor object in each loop. You lost nothing: niether memory leaks no app+db crashes.

Related

How to put this cursor data in ArrayLists - AndroidStudio

I have a cursorLoader which returns a cursor with this data:
0 {
email=bogdan#gmail.com
about=Party
}
1 {
email=bogdan1#gmail.com
about=Paaarty
}
2 {
email=bogdan2#gmail.com
about=activity 2
}
3 {
email=bogdan3#gmail.com
about=activity 3
}
4 {
email=bogdan4#gmail.com
about=activity 5
}
How can I save the emails in an ArrayList called emails and the about in an ArrayList called about. I've been trying different things with the cursor but most of the time I just get outOfBounds.
Edit: This is the line that prints it like that:
Log.v("Cursor Object", DatabaseUtils.dumpCursorToString(cursor));
If you want to do it your way maybe this method would help (provided that you supply two empty ArrayList) ?
private void populateLists(Cursor cursor, List<String> emails,
List<String> about) throws IllegalArgumentException {
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
do {
emails.add(cursor.getString(cursor
.getColumnIndexOrThrow("email")));
about.add(cursor.getString(cursor
.getColumnIndexOrThrow("about")));
} while (cursor.moveToNext());
}
}

Collect data from sqlite and display it in TextView

I was able to be extracted the data that interest me in this way:
Cursor stipcursor = dataBase.rawQuery("SELECT (riepilogo) AS stip FROM "+DbHelper.RIEPILOGO+" WHERE MESI = 'Gennaio' and ANNI = "+anno+"", null);
int colIndexstip = stipcursor.getColumnIndex("stip");
if (colIndexstip == -1)
return;
else
stipcursor.moveToFirst();
double stip = stipcursor.getDouble(colIndexstip);
System.out.println("Riepilogo"+stip);
the problem is that if the database has data, everything works, but if the database is empty, the application crashes.
As given in this post, try this
if ( cursor.moveToFirst() ) {
// start activity a
} else {
// start activity b
}
cursor.moveToFirst() will return false if the cursor is empty. It works for me always.
You can try the first method given on that post also.

Cursor for calls index out of bound

I am trying to parse all the log of calls, but when ONLY the first call ends, the cursor is out of bound. It throws 2 exceptions (for date and duration)
Thank you in advance
My code is here:
if (c != null && c.getCount()>0) {
if (c.moveToFirst()) {!
type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));
do {
try{
Log.d(this.getClass().getName(),"Date is "+c.getString(c.getColumnIndex(Calls.DATE)));
}catch(Exception e){
Log.d(this.getClass().getName(),"Exception: DATE IS NULL!!");
}
//String timestamp = c.getString(c.getColumnIndex(Calls.DATE));
//Log.d(this.getClass().getName(),"timestamp is: "+timestamp);
try{
long duration= c.getLong(c.getColumnIndex(CallLog.Calls.DURATION));
}catch(Exception e){
Log.d(this.getClass().getName(),"Exception: DURATION IS NULL!!");
}
//callDuration.put(timestamp, duration);
}
while (!c.moveToNext());
}
}
Since this is a do - while loop, I think the condition needs to be true for the loop to continue.
So your code should say
do {
this
}
while (c.moveToNext());
When the condition becomes false, the loop will exit.
The explanation is here - http://docs.oracle.com/javase/tutorial/java/nutsandbolts/while.html

problems with cursor and getting data?

I have created a table and trying to fetch data from it using a cursor as follow:
public Cursor getcontent() {
Cursor d = database.query(DatabaseHandler.Table_Name2,allColumns,selection, null, null,null,null);
return d;
}
Cursor r = X.getcontent();
if (r.getCount() > 0) {
r.moveToFirst();
do {
String id = r.getString(r.getColumnIndex("content_id"));
al.add(id);
MainActivity.tt1.append("\n");
MainActivity.tt1.append(id);
} while (r.moveToNext()==true);
r.close();
} else {
Log.i("TAG"," No value found");
}
}
I am showing the result in the TextView to see what data it is fetched. My problem is when I run this code sometimes it shows the data in the TextView, whatever it has fetched and sometimes it doesn't. Its a 50:50 ratio, according to me it should show fetched values every time as data is fetched every time I don't know what is wrong here, can someone tell me what's the issue here?
Check Whether Cursor you are getting is Null or not . and if yes then What is the Count of Cursor. you can Do it by Below Way.
Cursor r = X.getcontent();
if ((r != null) && (r.getCount() > 0)) {
r.moveToFirst();
do {
String id = r.getString(r.getColumnIndex("content_id"));
al.add(id);
MainActivity.tt1.append("\n");
MainActivity.tt1.append(id);
} while (r.moveToNext());
r.close();
} else {
Log.i("TAG"," No value found inside Cursor");
}
try like this
Cursor r = X.getcontent();
try {
if (r.moveToFirst()) {
do {
String id = r.getString(r.getColumnIndex("content_id"));
al.add(id);
MainActivity.tt1.append("\n");
MainActivity.tt1.append(id);
} while (r.moveToNext());
}
} finally {
if(r!=null) {
r.close();
}
}

Cursor Exception

I have created a database and i want to retrieve some data from the database by using the cursor by i always get this error
04-19 20:02:56.747: E/AndroidRuntime(301): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
04-19 20:02:56.747: E/AndroidRuntime(301): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
04-19 20:02:56.747: E/AndroidRuntime(301): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
04-19 20:02:56.747: E/AndroidRuntime(301): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
here is the code of the function
public double getlatitude(String[] i,int x) {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_SQUAREID, KEY_SQUARELATITUDE, KEY_SQUARENAME,
KEY_SQUARELONGITUDE
};
Cursor c;
c=ourDatabase.query("squares", columns,"squarename=?",i, null, null, null);
String latitude = null;
if (c.moveToFirst()) {
latitude=c.getString(0);
}
double latitude_double=Double.parseDouble(latitude);
return latitude_double;
}
Try this
if(c.getCount() > 0) {
c.moveToFirst();
for(int i=0;i<c.getCount();i++) {
//do your logic here
}
}
The exception likely occurred because your cursor is empty (there may have been no match). To avoid this make sure that you check whether the cursor is empty or not, if it is empty then you should not try to access it. And if it is not empty, you should check the max row count and make sure that you don’t access to any row that is equal or higher than the max row count. See the code below:
if ( c != null && c.getCount() > 0 ) {
if (c.moveToFirst()) {
do {
// do something here
} while (c.moveToNext());
}
c.close();
}
I think the problem is here:
latitude=c.getString(0);
Change it to:
latitude = c.getString(c.getColumnIndex("column_name"));
and also dont forget to close your cursor before returning value by calling c.close();
Whenever you are dealing with Cursors, ALWAYS check for null and check for moveToFirst() without fail, if you want to avoid weird crashes in the future.
if( c != null ){
if( c.moveToFirst() ){
//Do your stuff
}
}
//After finishing always close the cursor.
c.close();

Categories

Resources