2010-11-08 81 views
2

我正在创建一个应用程序。我得到这个错误:发现SQLite数据库泄露

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

我似乎无法找到原因,因为它somethimes显示我的错误,有时不是。这里是我的代码:

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(); 
      } 
     } 
    } 
} 

在另一类,我有这些疑问:

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; 
    } 
} 

我的问题是,当我开始一个新的活动中,我得到一个AsyncTask。此任务从Web服务获取数据并访问String的数据库。这里是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; 
    } 
} 

如果我让活动的过程中,一切顺利。如果我没有,并快速按下后退按钮,我得到的错误。有关如何解决这个问题的任何建议?

回答

4

我不确定你是否正确使用SQLiteOpenHelper ......你不需要那个myDataBase字段,它的想法是它为你管理你的数据库连接。不要以这种方式没有继承......除非你在onCreate()等未张贴在这里,它看起来像你可以直接使用SQLiteOpenHelper,即做事:

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

假设结束活动应也停止你的后台任务,我建议你从Activity.onPause()拨打AsyncTask.cancel(true)。确保数据库从onCancelled()清除。

并且如果您的后台任务是读取数据库的唯一内容,那么使其拥有SQLiteOpenHelper实例。使用静态数据很容易出现问题,所以最好避免使用恕我直言。我会做这样的事情:

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

我觉得这个部分:

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

必须在终于接近像

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

也不要忘记关闭数据库onDestroy方法。

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

我们是否需要声明cursor = null; – 2018-01-22 07:11:03