【问题标题】:SQLite database leak found发现 SQLite 数据库泄漏
【发布时间】:2010-11-08 12:20:05
【问题描述】:

我正在创建一个应用程序。我收到此错误:

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 服务获取数据并访问 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;
     }
}

如果我让活动顺其自然,一切都会好起来的。如果我不快速按下后退按钮,我会收到错误消息。有关如何解决此问题的任何建议?

【问题讨论】:

    标签: android database sqlite android-sqlite


    【解决方案1】:

    不确定您是否正确使用了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();
      

      必须在finally 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;
      猜你喜欢
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      相关资源
      最近更新 更多