How to use CALLER_IS_SYNCADAPTER properly

元气小坏坏 提交于 2019-12-02 00:52:08

问题


somehow I don't understand the working concept of the query parameter CALLER_IS_SYNCADAPTER. Its default value is false, if set, the DIRTY flag is not automatically set. So what does it actually mean? Out from my understanding, each change on a contact results in setting the dirty flag to 1. After a sync adapter finished the job, using insert/update/delete with the CALLER_IS_SYNCADAPTER the inserted/updated and deleted records should have a dirty flag of 0, is that right?

However if I invoke queries with that optional parameter, the entries remain with the flag 1.

Is there something else I have to do, or is my understanding how it should work wrong? Or is there something to tell the system the sync has been finished successfully to set the flags?

Does anybody have a sample or some advices for further reading?


回答1:


CALLER_IS_SYNCADAPTER doesn't necessarily affect what's stored in the database row, it depends on the command performed. It shouldn't have an effect on queries. Do not use it from a user application on the device.

Now... Why does it exist?

It is provided to help with notifyChange() / ContentObservers / ContentResolver / Syncadapter integration. There are two use cases for changing a row in the database.

  1. Local user edits from an application.
  2. Changes come from the network (via SyncAdapter)

Either change requires the UI to update, if it's onscreen. Therefore ContentResolver.notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) gets called. This updates ContentObservers and tells them to go fetch the newest data from the ContentProvider DB. That last parameter in the call is your clue.

ContentResolver itself is a ContentObserver. When it sees the database change, it considers starting up your SyncAdapter to push the change up to the network. This is great in case 1. In case 2, it's redundant. The change came from the network, there's no reason at all to start up a sync to send the change back.

Calendar.CALLER_IS_SYNCADAPTER is a cue used within the update() performed by the SyncAdapter. When it's true, ContentProvider sets syncToNetwork as false, ensuring a redundant second sync is not performed

A second example is as veljko mentioned. The cleanest way to delete a thing from the server is to set the delete flag, and then perform a sync. When the CALLER_IS_SYNCADAPTER flag is false (user app) a call to delete() sets the flag. When the flag is true (sync is happening), a call to delete() pushes the deletion up to the server and removes the row from the local DB. There's only one delete() call, this flag allows the ContentProvider to know which task it's supposed to do.




回答2:


You can add to your existing Uri:

myUri=calendarUri.buildUpon().appendQueryParameter(Calendar.CALLER_IS_SYNCADAPTER, "true").build();



回答3:


Here is from Javadoc:

/** * An optional insert, update or delete URI parameter that allows the caller * to specify that it is a sync adapter. The default value is false. If true * the dirty flag is not automatically set and the "syncToNetwork" parameter * is set to false when calling * {@link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}. */

.

The invocation of resolver.delete(...), does not immediately delete a raw contacts row. Instead, it sets the DELETED flag on the raw contact and removes the raw contact from its aggregate contact. The sync adapter then deletes the raw contact from the server and finalizes phone-side deletion by calling resolver.delete(...) again and passing the CALLER_IS_SYNCADAPTER query parameter.



来源:https://stackoverflow.com/questions/6969522/how-to-use-caller-is-syncadapter-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!