2010-11-08 5 views
2

Je crée une application. Je reçois cette erreur:Fuite de base de données SQLite trouvée

11-08 13:46:24.665: ERROR/Database(443): java.lang.IllegalStateException: /data/data/com.testproj/databases/Testdb SQLiteDatabase created and never closed

Je ne peux pas sembler trouver la raison de cela, comme il Somethimes me montre l'erreur, parfois pas. Voici mon code:

public class SQLiteAssistant extends SQLiteOpenHelper { 
    public SQLiteAssistant(Context context){ 
      super(context, DB_NAME, null, DB_VERSION_NUMBER); 
      this.myContext = context; 
    } 

    public void openDataBase() throws SQLException{ 
     String myPath = DB_PATH + DB_NAME; 
     myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 
    } 

    public void closeDataBase() { 
     if(this.myDataBase != null) { 
      if(this.myDataBase.isOpen()) 
       this.myDataBase.close(); 
      } 
     } 
    } 
} 

Dans une autre classe, j'ai ces requêtes:

public class Db{ 

    private static SQLiteAssistant sqlite; 

    public static String getSomeString(Context ctx) { 

     sqlite = new SQLiteAssistant(ctx); 
     sqlite.openDataBase(); 

     Cursor cursor = sqlite.myDataBase.rawQuery("SELECT someColumn from SomeTable",null); 

     if (cursor != null) { 
      if (cursor.getCount()==1) { 
       if(cursor.moveToFirst()) { 
        String testString = cursor.getString(cursor.getColumnIndex("someColumn")); 
        cursor.close(); 
        sqlite.closeDataBase(); 
        sqlite.close(); 
        return testString 
       } 
      } 
     } 

     sqlite.closeDataBase(); 
     sqlite.close(); 

     return null; 
    } 
} 

Mon problème est quand je commence une nouvelle activité dans laquelle je reçois un AsyncTask. Cette tâche obtient des données à partir d'un service Web et accède à la base de données pour le String. Voici le AsyncTask:

protected class BackTask extends AsyncTask<Context, String, String> { 
    @Override 
    protected String doInBackground(Context... params) { 
     try{ 
      //get requeste data from the database 
      //access the web service 

      return result; 

     } catch (Exception e) { 
        return null; 
     } 
     return null; 
    } 
} 

Si je laisse l'activité suivre son cours, tout va bien. Si je ne le fais pas et appuyez rapidement sur le bouton de retour, j'obtiens l'erreur. Toute suggestion sur la façon de résoudre ce problème?

Répondre

4

Je ne suis pas sûr que vous utilisez SQLiteOpenHelper correctement ... vous n'avez pas besoin de ce champ myDataBase, l'idée est qu'il gère votre connexion de base de données pour vous. Ne pas sous-classe de cette façon ... à moins que vous faites les choses dans onCreate() etc qui ne sont pas affichés ici il semble que vous pouvez simplement utiliser directement SQLiteOpenHelper, à savoir:

SQLiteOpenHelper sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null, 
    DB_VERSION_NUMBER); 

En supposant que la fin de l'activité devrait arrêtez aussi votre tâche d'arrière-plan, je vous recommande d'appeler AsyncTask.cancel(true) depuis votre Activity.onPause(). Assurez-vous que la base de données est nettoyée de onCancelled(). Et si votre tâche d'arrière-plan est la seule chose qui lit la base de données, alors faites en sorte qu'elle possède l'instance SQLiteOpenHelper. Il est facile d'avoir des ennuis avec des données statiques, donc il vaut mieux éviter à mon humble avis. Je ferais quelque chose comme ceci:

protected class BackTask extends AsyncTask<String, Integer, String> 
{ 
    private SQLiteOpenHelper sqlite; 

    public void BackTask(Context ctx) { 
     sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null, 
             DB_VERSION_NUMBER); 
    } 
    @Override 
    protected String doInBackground(String... params) 
    { 
     try { 
       //get requeste data from the database 
       //access the web service 
       return result; 

       } catch (Exception e) { 
     } 
     return null; 
    } 

    @Override 
    protected void onCancelled() { 
     sqlite.close(); 
    } 

    @Override 
    protected void onPostExecute(String result) 
     sqlite.close(); 
     // Update UI here 
    } 
} 
2

Je pense que cette partie:

cursor.close(); 
       sqlite.closeDataBase(); 
         sqlite.close(); 

doit être dans un proche enfin comme

Try{ 
    //Do something 
    } 
    catch(){ 
    //Catch exception 
    } 
    finally{ 
    //Close cursor or/and eventually close database if you don't need it in the future 
    } 

ne pas oublier de fermer la base de données en Méthode onDestroy

onCreate(Bundle b){ 
//create database instance 
} 
onDestroy{ 
//close db 
} 
+0

pouvons-nous avoir besoin de déclarer cursor = null; –

Questions connexes