SQLite database leak found

拜拜、爱过 提交于 2020-01-13 20:18:14

问题


I'm creating an application. I'm getting this error:

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

I can't seem to find the reason for this, as it somethimes shows me the error, sometimes not. Here is my 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();
            }
        }   
    }
}

In another class, I have these queries:

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

My problem is when I start a new activity in which I get an AsyncTask. This task gets data from a web service and accesses the database for the String. Here is the 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;
     }
}

If I let the activity take its course, everything goes fine. If I don't and quickly press the back button, I get the error. Any suggestion on how to solve this problem?


回答1:


Am not sure you're using SQLiteOpenHelper properly... you don't need that myDataBase field, the idea is that it manages your database connection for you. Don't subclass in that way... unless you're doing things in onCreate() etc that aren't posted here it looks like you can just use SQLiteOpenHelper directly, i.e.:

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

Assuming that ending the activity should also stop your background task, I'd recommend calling AsyncTask.cancel(true) from your Activity.onPause(). Ensure the database is cleaned up from onCancelled().

And if your background task is the only thing reading the database then make it own the SQLiteOpenHelper instance. It's easy to get into trouble with static data, so it's best avoided IMHO. I'd do something like this:

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:


I think this part :

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

must be in a finally close like

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

Also don't forget to close database in onDestroy method .

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


来源:https://stackoverflow.com/questions/4123749/sqlite-database-leak-found

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!