在ContentObserver类中,onChange方法被传递一个boolean selfchange,其定义为:“如果更新是由正在观察的游标上的commit调用引起的,则为true。”
更新光标使selfchange设置为true的正确方法是什么?我当前的代码根本不引用游标进行更新,因此selfchange始终为false。
ContentValues values = new ContentValues();
values.put("date", date.getTime());
getContentResolver().update(URI, values, "_id = " + id, null);
最佳答案
android框架没有提供通过staticContentResolver#update()
方法实现这一点的方法。
解释
当使用ContentResolver#notifyChange(Uri,ContentObserver)
对象作为发起更改的观察者调用ContentObserver
时,该ContentObserver
将使用设置为true的onChange()
调用selfChange
。
从文档中:
void android.content.contentresolver.notifychange(uri uri,content observer观察员)
参数:
uri更改的内容的uri。
观察家
发起更改的观察者可能为空。观察者
发起更改只有在
请求通过实现
contentObserver.deliverselfNotifications()返回true。
因此,如果您从notifyChange()
update/insert/delete方法中调用ContentProvider
,而这些方法又是从ContentResolver
update/insert/delete方法调用的,那么您将没有要传递到ContentObserver
的notifyChange()
引用,因此也不会将selfChange
设置为true。
解决办法
如果ContentProvider与客户机代码处于同一进程中,则此操作将起作用。它需要一个自定义的contentprovider和一个更复杂/更容易出错的update/insert/delete方法调用。
我们可以在派生的ContentProvider
中创建以ContentObserver
为参数的自定义方法。例如,如果我们想用update()
调用notifyChange()
方法,我们可以这样做:
public class MyContentProvider extends ContentProvider {
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// Just call our new method with 'null' as the ContentObserver
update(uri,values,selection,selectionArgs,null);
}
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs, ContentObserver changeOriginator){
// Do the update
...
// Notify the change with the ContentObserver that wants to ignore it
getContext().getContentResolver().notifyChange(uri,changeOriginator);
}
要使用新方法,您必须从
ContentObserver
中获取ContentProvider
对象并调用我们的新ContentResolver
方法:ContentProvider cP = getContentResolver().acquireContentProviderClient(URI).getLocalContentProvider();
MyContentProvider mCP = (MyContentProvider)cP;
mCP.update(URI, values, "_id = " + id, null, contentProvider);