发现SQLite数据库泄漏 [英] SQLite database leak found

查看:106
本文介绍了发现SQLite数据库泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

我的问题是,当我开始一个新活动时,我得到一个AsyncTask.此任务从Web服务获取数据并访问String的数据库.这是AsyncTask:

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?

推荐答案

如果不确定您是否正确使用了SQLiteOpenHelper,则不需要该myDataBase字段,因为它可以管理数据库为您连接.不要以这种方式子类化...除非您正在使用onCreate()等未在此处发布的内容,否则看起来您可以直接使用SQLiteOpenHelper,即:

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

假设结束活动也应该停止您的后台任务,建议您致电Activity.onPause()中的rel ="nofollow"> AsyncTask.cancel(true) .确保从onCancelled()中清除了数据库.

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().

如果只有后台任务是读取数据库的内容,则使其成为SQLiteOpenHelper实例的所有者.静态数据很容易引起麻烦,因此最好避免恕我直言.我会做这样的事情:

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

这篇关于发现SQLite数据库泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆