我有一个ContentProvider。有我的查询和插入方法:
@Override
public Uri insert(Uri uri, ContentValues values) {
final int match = sUriMatcher.match(uri);
long id = -1;
switch (match) {
case ARTICLES_LIST:
id = ArticlesDataSource.getInstance().addArticle(values);
break;
}
Log.d(LOG_TAG, "Notify change for URI: " + uri);
getContext().getContentResolver().notifyChange(uri, null);
if (id != -1) {
return ArticleContract.buildArticleWithIdUri(id);
}
return null;
}
和
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
final int match = sUriMatcher.match(uri);
Cursor refCursor = null;
switch (match) {
case ARTICLES_LIST:
refCursor = ArticlesDataSource.getInstance().getAllPreviewArticlesCursor(selectionArgs, selection, selectionArgs, sortOrder);
break;
case ARTICLES_LIST_BY_CATEGORY:
Article.Category category = ArticleContract.getCategoryFromUri(uri);
refCursor = ArticlesDataSource.getInstance().getPreviewArticlesCursorByCategory(selectionArgs, selection, selectionArgs, sortOrder, category);
//Modify uri for correct listener behaviour. Full uri is: content://payspace.ssidit.pp.ua.payspacemagazine/articles/category/categoryName
List<String> segments = uri.getPathSegments();
String lastSegment = segments.get(segments.size() - 2);
String uriStr = uri.toString();
uri = Uri.parse(uriStr.substring(0, uriStr.indexOf(lastSegment) - 1));
break;
default:
throw new UnsupportedOperationException("Unknwon uri: " + uri);
}
Log.d(LOG_TAG, "Registered for observe changes in uri: " + uri.toString());
refCursor.setNotificationUri(getContext().getContentResolver(), uri);
return refCursor;
}
我的notifyChange()和setNotificationUri()的日志:
已注册观察uri的变化:content://payspace.ssidit.pp.ua.payspacemagazine/articles
通知更改URI:content://payspace.ssidit.pp.ua.payspacemagazine/articles
如你所见,uris是平等的。内容添加到数据库中。我没有在我的代码中关闭光标。什么可能是错的?
UPDATE1: 我如何构建和处理CursorAdapter。 当应用启动时,会调用:
mListAdapter = new SimpleCursorAdapter(getActivity(), R.layout.article_list_item, null, from, to, 0);
然后我从数据库加载一些数据。 DatabaseCursorLoader代码:
public class DatabaseCursorLoader extends CursorLoader {
public static final String LOG_TAG = DatabaseCursorLoader.class.getName();
private int limit;
private Article.Category category;
public DatabaseCursorLoader(Context context, Article.Category category, int limit) {
super(context);
this.category = category;
this.limit = limit;
}
@Override
public Cursor loadInBackground() {
return getContext().getContentResolver().query(ArticleContract.buildArticlesWithCategoryUri(category), ArticlesDataSource.previewColumns, null, null, Article.KEY_DATE + " DESC LIMIT " + limit);
}
}
并交换光标:
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
int id = loader.getId();
switch (id) {
case LOADER_PREVIEWS_DB:
int loaded = cursor.getCount();
Log.d(LOG_TAG, "Rows in cursor " + loaded);
//если мы ничего не загрузили (не осталось новых записей из БД)
if (loaded - wasLoaded == 0) {
Log.d(LOG_TAG, "Starting service to load new data");
Intent intent = new Intent(getActivity(), LoadPreviewsService.class);
intent.putExtra(Article.KEY_CATEGORY, mCurrentCategory.ordinal());
intent.putExtra(Article.KEY_PAGE, mCurrentPage);
getActivity().startService(intent);
}
wasLoaded = loaded;
Log.d(LOG_TAG, "Swapped cursor");
mListAdapter.swapCursor(cursor);
break;
}
}
UPDATE2: 问题是我已经扩展了CursorLoader类,所以我认为我需要覆盖一些额外的方法来正确工作。我刚刚改变了:
loader = new DatabaseCursorLoader(getActivity(), category, page * ARTICLES_PER_PAGE);
到
loader = new CursorLoader(getActivity(), ArticleContract.buildArticlesWithCategoryUri(category), ArticlesDataSource.previewColumns, null, null, Article.KEY_DATE + " DESC LIMIT " + (page * ARTICLES_PER_PAGE));
它有效。非常感谢@pskink!