Android 发现SQLite数据库泄漏

Android 发现SQLite数据库泄漏,android,database,sqlite,android-sqlite,Android,Database,Sqlite,Android Sqlite,我正在创建一个应用程序。我得到了这个错误: 11-08 13:46:24.665:错误/数据库(443): java.lang.IllegalStateException: /data/data/com.testproj/databases/Testdb SQLiteDatabase已创建和 永不关闭 我似乎找不到这样做的原因,因为它有时会向我显示错误,有时不会。这是我的密码: public class SQLiteAssistant extends SQLiteOpenHelper {

我正在创建一个应用程序。我得到了这个错误:

11-08 13:46:24.665:错误/数据库(443): java.lang.IllegalStateException: /data/data/com.testproj/databases/Testdb SQLiteDatabase已创建和 永不关闭

我似乎找不到这样做的原因,因为它有时会向我显示错误,有时不会。这是我的密码:

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服务获取数据,并访问
字符串的数据库。以下是
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;
     }
}
受保护的类BackTask扩展了异步任务{
@凌驾
受保护字符串doInBackground(上下文…参数){
试一试{
//从数据库获取请求数据
//访问web服务
返回结果;
}捕获(例外e){
返回null;
}
返回null;
}
}

如果我听其自然,一切都会好起来。如果我不这样做,并迅速按下后退按钮,我得到的错误。关于如何解决这个问题有什么建议吗?

我不确定您是否正确使用了
SQLiteOpenHelper
。。。您不需要
myDataBase
字段,其目的是为您管理数据库连接。不要这样子类化。。。除非您在
onCreate()
等中执行此处未发布的操作,否则看起来您可以直接使用
SQLiteOpenHelper
,即:

SQLiteOpenHelper sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null,
    DB_VERSION_NUMBER);
假设结束活动也会停止后台任务,我建议您从
activity.onPause()调用
。确保已从onCancelled()清除数据库

如果后台任务是读取数据库的唯一任务,那么就让它拥有SQLiteOpenHelper实例。静态数据很容易出现问题,因此最好避免使用IMHO。我会这样做:

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
    }
}
受保护的类BackTask扩展了异步任务
{
私有SQLiteOpenHelper sqlite;
公共void BackTask(上下文ctx){
sqlite=newSQLiteOpenHelper(ctx,DB_路径+DB_名称,null,
DB_版本_编号);
}
@凌驾
受保护的字符串doInBackground(字符串…参数)
{
试一试{
//从数据库获取请求数据
//访问web服务
返回结果;
}捕获(例外e){
}
返回null;
}
@凌驾
受保护的void onCancelled(){
sqlite.close();
}
@凌驾
受保护的void onPostExecute(字符串结果)
sqlite.close();
//在此处更新用户界面
}
}
我认为这一部分:

 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
}

我们是否需要声明cursor=null;