1

I have a really weird problem that i am not able to reproduce neither on emulator or on any of the tested android devices.

I have a SQlite Database controller that holds all of mine data access functions, in this class i have a simple function to check if a table exists:

public boolean tableExists(String tableName) {   
  if(db==null || !db.isOpen()) db =  dbhelper.getWritableDatabase();      
  Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='"+tableName+"'", null);
       if(cursor!=null) {
           if(cursor.getCount()>0) {
              cursor.close();
              return true;
             }
            cursor.close();
          }
      return false;  
    }

On my application start i create an async task to check for updates and on this process i will check for the existence of a local table in the database.

The error thrown is on the Cursor cursor = db.rawQuery(... line, and the error is:

java.lang.IllegalStateException: database ... db.sqlite already closed

java.lang.RuntimeException: An error occured while executing doInBackground()
 at android.os.AsyncTask$3.done(AsyncTask.java:200)
 at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
 at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
 at java.util.concurrent.FutureTask.run(FutureTask.java:138)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
 at java.lang.Thread.run(Thread.java:1019)
Caused by: java.lang.IllegalStateException: database /data/data/com.xxx.xxx.xxx.android/databases/db.sqlite already closed
 at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:59)
 at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
 at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
 at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
 at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1364)
 at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1332)
 at com.xxx.xxx.xxx.utils.SQLiteController.tableExists(SQLiteController.java:1463)

I am not able to reproduce this error but according to ACRA this is happening several times in different devices.

Can someone give me a light on this?

Thanks.

Mario Santos
  • 896
  • 7
  • 8
  • ... since this code is in AsyncTask, check if it is not called twice (i mean two AsyncTask running concurrently) – Selvin Sep 14 '12 at 09:10
  • Thanks, i have checked and it seems not. That could be a valid point as they could be recreated on orientation changes, but the specific async task is not triggered on prior orientation changes. So i'm still stuck. – Mario Santos Sep 14 '12 at 09:50

1 Answers1

0

Please put that second cursor.close(); inside the else blocks follows

public boolean tableExists(String tableName) {   
  if(db==null || !db.isOpen()) db =  dbhelper.getWritableDatabase();      
  Cursor cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='"+tableName+"'", null);
       if(cursor!=null) {
           if(cursor.getCount()>0) {
              cursor.close();
              return true;
             }
          else{
                  cursor.close();
              }  
             }
      return false;  
    }
Manoj Kumar
  • 1,510
  • 3
  • 20
  • 40
  • 1
    It does not seem to be the source of the problem. The error is on the rawQuery line. And the else is executed if the cursor.getCount()>0 is not true: Correct, but that still happens on my code, if the if statement is true it returns true and the code is stopped, function exit. The cursor.close() will never be executed twice. – Mario Santos Sep 14 '12 at 08:44
  • @Mojo could you tell us what for? – Selvin Sep 14 '12 at 08:45
  • i posted for the scenario IF is succeeded, the the cursor will close inside, but again you're trying to close it; – Manoj Kumar Sep 14 '12 at 08:48
  • yeah, sure Mojo ... after `return` statment ... did you take something ? – Selvin Sep 14 '12 at 08:51
  • just check cursor.moveToFirst() condition after cursot not null exception, also try cursor.isBeforeFirst() condition; – Manoj Kumar Sep 14 '12 at 08:55
  • its checking the count but doen't check its position ; pls try it dude:) you never know what mi8 come :P – Manoj Kumar Sep 14 '12 at 09:18