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