Android CursorWrapperInner:未事先关闭的游标已完成()

Android CursorWrapperInner:未事先关闭的游标已完成(),android,sqlite,android-contentprovider,Android,Sqlite,Android Contentprovider,我已经建立了一个rss新闻应用程序。它在某种程度上运行良好,但有一些bug。问题是,内容提供商并没有为某些rss源添加新新闻,并且在日志中并没有出现之前的close()错误的情况下完成游标。我正在后台维护服务中刷新提要。如果可能,需要改进性能 private int refreshLocalFeed(Feeds feeds) throws RemoteException, OperationApplicationException { LogMessage.d("feed refres

我已经建立了一个rss新闻应用程序。它在某种程度上运行良好,但有一些bug。问题是,内容提供商并没有为某些rss源添加新新闻,并且在日志中并没有出现之前的close()错误的情况下完成游标。我正在后台维护服务中刷新提要。如果可能,需要改进性能

private int refreshLocalFeed(Feeds feeds) throws RemoteException, OperationApplicationException {

    LogMessage.d("feed refresh:", feeds.getCategoryId() + " : " + feeds.getName());
    Call<RSSFeed2> call = api.loadOwnRssFeed(feeds.getUrl());
    ContentResolver cr = MyApp.getAppContext().getContentResolver();
    int success = 0;
    try {
        Response<RSSFeed2> response = call.execute();
        RSSFeed2 rssFeed = response.body();
        if (rssFeed != null) {
            ArrayList<ContentProviderOperation> operations = new ArrayList<>();
            Collections.reverse(rssFeed.getArticleList());
            for (Article article : rssFeed.getArticleList()) {

                Cursor c = null;
                try {
                    c = cr.query(DbContract.EntryColumns.CONTENT_URI, new String[]{DbContract.EntryColumns._ID}, DbContract.EntryColumns.CATEGORYID + "=? AND " + DbContract.EntryColumns.LINK + "=?",
                            new String[]{feeds.getCategoryId(), article.getLink()}, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                ContentValues values = new ContentValues();
                values.put(DbContract.EntryColumns.TITLE, article.getTitle());
                values.put(DbContract.EntryColumns.DESCRIPTION, article.getDescription());
                values.put(DbContract.EntryColumns.DATE, article.getPubDate());
                values.put(DbContract.EntryColumns.AUTHOR, getString(R.string.app_name));
                values.put(DbContract.EntryColumns.FETCH_DATE, System.currentTimeMillis());
                values.put(DbContract.EntryColumns.CATEGORYID, feeds.getCategoryId());
                values.put(DbContract.EntryColumns.GUID, article.getGuid());

                String alternateImageUrl = getImageUrl(article.getDescription());
                if (article.getThumbnail() != null && !article.getThumbnail().isEmpty()) {
                    values.put(DbContract.EntryColumns.IMAGE_URL, article.getThumbnail());
                } else if (!alternateImageUrl.isEmpty()) {
                    values.put(DbContract.EntryColumns.IMAGE_URL, getImageUrl(article.getDescription()));
                }
                values.put(DbContract.EntryColumns.LINK, article.getLink());

                if (c != null && c.getCount() > 0) {
                    operations.add(ContentProviderOperation.newUpdate(DbContract.EntryColumns.CONTENT_URI)
                            .withSelection(DbContract.EntryColumns._ID, new String[]{String.valueOf(c.getInt(c.getColumnIndexOrThrow(DbContract.EntryColumns._ID)))})
                            .withValues(values)
                            .build());
                    c.close();
                } else {
                    operations.add(ContentProviderOperation.newInsert(DbContract.EntryColumns.CONTENT_URI)
                            .withValues(values)
                            .build());

                }
            }
            ContentProviderResult[] results = cr.applyBatch(DbContract.AUTHORITY, operations);
            for (ContentProviderResult result : results) {
                if (result.uri != null) {
                    success++;
                }
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
    return success;
}

只有在提取行时才关闭光标,即
c.getCount()>0
,处理完光标后应始终关闭光标。注意,没有行的游标仍然是有效的游标,应该关闭。@MikeT,我已经更新了代码。但它在日志中仍然给出了相同的错误。@MikeT,可以在ContentResolver.applyBatch(operationslist)中插入和更新它们吗?我不确定,我从未使用过ContentResolver。但是,如果您正在做多个更改,那么您可以考虑使用DB。如果填充工作正常,是否填充db.setTransactionSuccessful()以及db.endTransaction()是否正常。
if (c != null) {
    if (c.getCount() > 0) {
        operations.add(ContentProviderOperation.newUpdate(DbContract.EntryColumns.CONTENT_URI)
                                .withSelection(DbContract.EntryColumns._ID, new String[]{String.valueOf(c.getInt(c.getColumnIndexOrThrow(DbContract.EntryColumns._ID)))})
                                .withValues(values)
                                .build());
    }
    c.close();
} else {
        operations.add(ContentProviderOperation.newInsert(DbContract.EntryColumns.CONTENT_URI)
                            .withValues(values)
                            .build());
    }