Android 使用内容提供程序从数据库加载数据
我使用内容提供者来存储和检索数据库中的数据。这就是用户安装应用程序时应用程序中发生的情况Android 使用内容提供程序从数据库加载数据,android,android-contentprovider,android-contentresolver,android-cursorloader,android-loadermanager,Android,Android Contentprovider,Android Contentresolver,Android Cursorloader,Android Loadermanager,我使用内容提供者来存储和检索数据库中的数据。这就是用户安装应用程序时应用程序中发生的情况 应用程序启动一项服务,该服务将从服务器下载数据并存储 它以db表示 应用程序正在使用CursorLoader从数据库加载数据 问题是,在服务下载并存储数据之前,数据库中第一次并没有任何数据。当这种情况发生时,CursorLoader不会从db加载数据。如果我关闭并重新打开应用程序,它会从db加载数据 这就是我如何使用ContentProvider @Override public int bulkInser
CursorLoader
从数据库加载数据ContentProvider
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
final SQLiteDatabase db = feederDbHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
switch (match) {
case CODE_INSERT_SOURCE:
//Return the number of rows inserted from our implementation of bulkInsert
return insertRecords(FeederContract.SourceEntry.TABLE_NAME, db, values, uri);
case CODE_INSERT_ARTICLE:
return insertRecords(FeederContract.ArticleEntry.TABLE_NAME, db, values, uri);
default:
return super.bulkInsert(uri, values);
}
}
下面是insertRecords
方法
public int insertRecords(String tabbleName, SQLiteDatabase db, ContentValues[] values, Uri uri) {
db.beginTransaction();
int rowsInserted = 0;
try {
for (ContentValues value : values) {
long _id = db.insertWithOnConflict(tabbleName, null, value, SQLiteDatabase.CONFLICT_REPLACE);
if (_id != -1) {
rowsInserted++;
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (rowsInserted > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
//Return the number of rows inserted from our implementation of bulkInsert
return rowsInserted;
}
以下是用户第一次启动应用程序时发生的情况。我也添加了评论
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.feeds_fragment, container, false);
ButterKnife.bind(this, view);
loadAd();
initRc();
// Starting service to download feeds
FeederSyncUtil.startSync(getActivity());
// Starting loader to load feeds
getActivity().getSupportLoaderManager().initLoader(ID_FEEDS_LOADER, null, this);
return view;
}
这些是加载程序回调
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
FeederContract.ArticleEntry.CONTENT_URI,
MAIN_FEED_PROJECTION,
null,
null,
null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.d(TAG, data.getCount() + "");
mFeedsAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mFeedsAdapter.swapCursor(null);
}
@覆盖
公共加载器onCreateLoader(int-id,Bundle-args){
返回新的游标装入器(getActivity(),
FeederContract.ArticleEntry.CONTENT\u URI,
主馈电投影,
无效的
无效的
无效);
}
@凌驾
public void onLoadFinished(加载器、光标数据){
Log.d(标记,data.getCount()+);
mFeedsAdapter.swapCursor(数据);
}
@凌驾
公共void onLoaderReset(加载器){
mFeedsAdapter.swapCursor(空);
}
我错过了什么?尽管我使用的是
getContext().getContentResolver().notifyChange(uri,null)
,但它仍然不会刷新光标
,请提供一些指导。错误!我遗漏了一些东西。我花了几个小时在这个问题上到处寻找,然后我进入文档,找到了这个方法
/**
* Register to watch a content URI for changes. This can be the URI of a specific data row (for
* example, "content://my_provider_type/23"), or a a generic URI for a content type.
*
* @param cr The content resolver from the caller's context. The listener attached to
* this resolver will be notified.
* @param uri The content URI to watch.
*/
void setNotificationUri(ContentResolver cr, Uri uri);
因此,我在提供者的query
方法中添加了对该方法的连接调用。
下面是我的提供者的一些代码片段
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
int match = sUriMatcher.match(uri);
Cursor cursor = null;
switch (match) {
case CODE_INSERT_SOURCE:
cursor = feederDbHelper.getReadableDatabase().query(FeederContract.SourceEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
break;
case CODE_VIEW_ARTICLE:
cursor = feederDbHelper.getReadableDatabase().query(FeederContract.ArticleEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
break;
default:
throw new UnsupportedOperationException("Unknown uri " + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(),uri);
return cursor;
}
所以这一行cursor.setNotificationUri(getContext().getContentResolver(),uri)代码>
所有的魔力都在这里。当使用insert()
,delete()
,update()
,bulkInsert()
对URI基础数据进行任何更改时,它会将更改通知contentresolver。
由于CursorLoader
不会自动检测数据更改,我们需要使用setNotificationUri(ContentResolver cr,Uri-Uri)代码>
我希望这会对某人有所帮助。:)