下载SQLite数据库和泄漏的警告 [英] Downloaded SQLite database and leak warnings

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

问题描述

我做了一个使用下载的SQLite数据库的应用程序。要检索我使用的ContentProvider 在它的数据。当我需要读取数据库,我总是(我查过至少五次)使用code是这样的:

 光标C =的getContext()。getContentResolver()查询(MyContentProvider.ITEMSURI,
        突起,其中,NULL,NULL);
如果(c.moveToFirst()){
    而(!c.isAfterLast()){
        itemsList.add(cursorToItem(C));
        c.moveToNext();
    }
}
如果(C!= NULL)c.close();

不过,我不断收到类似这样的很多错误(我进行查询的序列在for循环中):

  10-18 13:16:01.709:W / SQLiteConnectionPool(27704):一个SQLiteConnection对象
为数据库'/storage/emulated/0/MyAPP/mydb.sqlite'被泄露!
请修正您的应用程序正确,并结束正在进行的交易
关闭数据库时不再需要它。

这是什么原因所有这些警告?光标总是关闭,并在的ContentProvider 没有必要关闭数据库。

code:

这是管理数据库类:

 公共类OpenMyDBHelper {    私有静态最后弦乐DB_NAME =mydb.sqlite;
    私有静态最终文件DB_PATH =新的文件(
            MyAppFolderManager.getInternalMemoryFolder(),DB_NAME);    私人SQLiteDatabase分贝;    公共SQLiteDatabase的open(){
        DB = SQLiteDatabase.openDatabase(DB_PATH.getAbsolutePath(),空,
                SQLiteDatabase.OPEN_READONLY);
        返回分贝;
    }    公共无效的close(){
        db.close();
    }}

这是我的的ContentProvider 子类:

 公共类MyContentProvider扩展ContentProvider的{    私人OpenMyDBHelper分贝;
    //静态路径/乌里定义....
    私人最终静态INT ITEMS = 1;
    私有静态最终UriMatcher sURIMatcher =新UriMatcher(
            UriMatcher.NO_MATCH);
    静态的 {
        sURIMatcher.addURI(权威,ITEMS_PATH,项目);
    }    @覆盖
    公共布尔的onCreate(){
        DB =新OpenMyDBHelper();
        返回false;
    }    @覆盖
    公共光标查询(URI URI,字符串[]投影,字符串的选择,
            的String [] selectionArgs两个,字符串中将sortOrder){
        光标光标= NULL;
        SQLiteDatabase数据库= db.open();
        INT uriType = sURIMatcher.match(URI);
        开关(uriType){
        案例项:
            光标= database.query(Constants.TABLE_ITEMS,
                    投影,选择,selectionArgs两个,NULL,NULL,
                    空值);
            cursor.setNotificationUri(的getContext()getContentResolver(),ITEMSURI);
            打破;
        默认:
            抛出新抛出:IllegalArgumentException(未知URI(+ URI +));
        }
        返回游标;
    }    @覆盖
    公共字符串的getType(URI URI){
        返回null;
    }    //这只是一个只读分贝,我不需要CUD操作...    @覆盖
    公共乌里插入(URI URI,ContentValues​​值){
        返回null;
    }    @覆盖
    公众诠释删除(URI URI,选择字符串,字符串[] selectionArgs两个){
        返回0;
    }    @覆盖
    公众诠释更新(开放的URI,ContentValues​​值,字符串的选择,
            的String [] selectionArgs两个){
        返回0;
    }
}


解决方案

  

这是什么原因所有这些警告?


您保留重新打开数据库中的事实。打开数据库的一次的,在的onCreate(),而不是每个查询()通话

不过,在所有诚实,如果你不执行完整的CRUD操作,我只是转储的ContentProvider ,因为你正在获得通过它什么。它也可能让你避免做一堆查询()在循环中调用和显著提高性能,通过使用运营商和这样的一个SQLite查询。

I've made an application that uses a downloaded SQLite database. To retrieve data in it I'm using a ContentProvider. When I need to read the database, I always (I've checked at least five times) use a code like this:

Cursor c = getContext().getContentResolver().query(MyContentProvider.ITEMSURI,
        projection,where,null,null);
if(c.moveToFirst()){
    while(!c.isAfterLast()){
        itemsList.add(cursorToItem(c));
        c.moveToNext();
    }
}
if(c!=null) c.close();

But I keep getting many errors like this (I make a sequence of queries in a for loop):

10-18 13:16:01.709: W/SQLiteConnectionPool(27704): A SQLiteConnection object 
for database '/storage/emulated/0/MyAPP/mydb.sqlite' was leaked!  
Please fix your application to end transactions in progress properly and to 
close the database when it is no longer needed.

What could cause all these warnings? Cursor is always closed and in ContentProvider there's no need to close database.

Code:

This is the class that manages the database:

public class OpenMyDBHelper{

    private static final String DB_NAME = "mydb.sqlite";
    private static final File DB_PATH = new File(
            MyAppFolderManager.getInternalMemoryFolder(), DB_NAME);

    private SQLiteDatabase db;

    public SQLiteDatabase open() {
        db = SQLiteDatabase.openDatabase(DB_PATH.getAbsolutePath(), null,
                SQLiteDatabase.OPEN_READONLY);
        return db;
    }

    public void close() {
        db.close();
    }

}

And this is my ContentProvider subclass:

public class MyContentProvider extends ContentProvider {

    private OpenMyDBHelper db;
    //static paths/Uri definitions....


    private final static int ITEMS = 1;
    private static final UriMatcher sURIMatcher = new UriMatcher(
            UriMatcher.NO_MATCH);
    static {
        sURIMatcher.addURI(AUTHORITY, ITEMS_PATH, ITEMS);
    }

    @Override
    public boolean onCreate() {
        db = new OpenMyDBHelper();
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        Cursor cursor = null;
        SQLiteDatabase database = db.open();
        int uriType = sURIMatcher.match(uri);
        switch (uriType) {
        case ITEMS:
            cursor = database.query(Constants.TABLE_ITEMS,
                    projection, selection, selectionArgs, null,null,
                    null);
            cursor.setNotificationUri(getContext().getContentResolver(), ITEMSURI);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI (" + uri + ")");
        }
        return cursor;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    //It's just a read-only db, I don't need the CUD operations...

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        return 0;
    }
}

解决方案

What could cause all these warnings?

The fact that you keep re-opening the database. Open the database once, in onCreate(), not on every query() call.

Though, in all honesty, if you are not implementing the full CRUD operations, I'd just dump the ContentProvider, as you are gaining nothing by it. It might also allow you to avoid doing a bunch of query() calls in a loop and significantly improve performance, by using IN operators and such in a SQLite query.

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

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