Downloaded SQLite database and leak warnings

独自空忆成欢 提交于 2019-12-11 04:15:12

问题


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

回答1:


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.




回答2:


If you have to use getReadableDatabase many times:

You can use this.close to close your database from leak. Example :

   public String getAdditionalInfo(final int id) {
        yourDB = this.getReadableDatabase();
        Cursor cursor = yourDB.rawQuery(selectQuery, null);
        if (cursor.moveToFirst()) {
            return cursor.getString(0);
        }
        cursor.close();
        this.close();// You add this line
        return "";
    }


来源:https://stackoverflow.com/questions/26439370/downloaded-sqlite-database-and-leak-warnings

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