数据库的SQLiteConnection对象被泄露

时间:2013-07-12 21:43:38

标签: android sqlite memory-leaks android-contentprovider

似乎每隔一次我测试这个应用程序,我收到消息,“数据库[路径]的SQLiteConnection对象被泄露!请修复您的应用程序以正确结束正在进行的事务并在没有时关闭数据库需要更长时间。“

我在这里看到了其他有关此消息的问题,但我不相信任何答案都适合我的情况。首先,我的所有数据库访问都是通过Content Provider进行的。另一方面,我正在处理多个数据库(两者都被泄露),以及许多用来保存其中一个数据库数据的游标。

我会发布内容提供商,但我的内容提供商是1200行。让我知道我应该选择哪些部分,我将编辑它们。如果它相关,那么Content Provider中有一个SQLiteOpenHelper内部类。否则,这是一个似乎导致此问题的活动的一部分:

private SimpleCursorAdapter setFixedSpinnerAdapter(String table, String[] columns){
        Uri uri = Uri.parse(DBContentProvider.CONTENT_URI_OPTION + table);
        String sortOrder = (columns.length > 2 ? columns[2] : columns[1]);
        //if 3rd column specified, use it for sorting
        Cursor cursor = getContentResolver().query(uri, columns, null, null, sortOrder);
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_dropdown_item, 
                cursor, new String[]{cursor.getColumnName(1)}, new int[]{android.R.id.text1}, 0);
        return adapter;
    }// method: setFixedSpinnerAdapter(String, String[])    

这段代码由多个Spinners调用,以获取将填充它们的数据行。如果你想知道,没有光标没有关闭,但我找不到关闭它的方法而不会丢失适配器中的数据。

因此,请告诉我您的任何想法,或者包含内容提供商部分内容的建议。

编辑:这是logcat

07-15 13:24:42.162: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.162: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.162: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.162: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.162: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.162: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.170: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.170: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.170: W/SQLiteConnectionPool(7394): A SQLiteConnection object for database '+data+data+edu_dordt_grassrootsplantid+databases+plant_identification_local' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
07-15 13:24:42.170: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.178: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.186: W/CursorWrapperInner(7394): Cursor finalized without prior close()
07-15 13:24:42.186: W/CursorWrapperInner(7394): Cursor finalized without prior close()

关于光标的线条对于这种尝试是新的,我相信,但正如我所说,当访问光标只能用于上述方法时,我不知道有什么方法可以关闭光标。此外,根据尝试,可能还有一些行说明了另一个数据库(通过应用程序的不同部分访问,但使用相同的内容提供商)也被泄露。

修改: 以下是Content Provider中查询方法的相关部分,如果它有帮助的话。

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
        String dbName;
        Cursor cursor;
        String tables;
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

        switch(uriMatcher.match(uri)){
            case CODE_OPTION_SEARCH://Called from setFixedSpinnerAdapter()
                dbName = DATABASE_PLANT_IDENTIFICATION_LOCAL;
                dbHelper = new DatabaseHelper(getContext(), dbName); 
                tables = uri.getLastPathSegment();
                db = dbHelper.getReadableDatabase();
                queryBuilder.setTables(tables);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI");
        }//switch(uriMatcher.match(uri))
        cursor = queryBuilder.query(db, projection, null, null, null, null, sortOrder);
        cursor.setNotificationUri(getContext().getContentResolver(), uri);

        return cursor;
    }// method: ContentProvider.query(Uri, String[], String, String[], String)

修改: 对于不同的微调器,我使用这种方式多次格式化的代码。

spnGrowthForm.setAdapter(setFixedSpinnerAdapter(
    DBContentProvider.TABLE_GROWTH_FORM_OPTION, 
    new String[]{DBContentProvider.KEY_GROWTH_FORM_ID,
    DBContentProvider.KEY_GROWTH_FORM_TEXT}));

方法setFixedSpinnerAdapter(String, String[])与发布在顶部的方法相同。我使用了SimpleCursorAdapter,因为这是我找到的唯一方法,可以让我访问与Spinner项目关联的ID#。

0 个答案:

没有答案