• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Sync on Android
 

Sync on Android

on

  • 3,994 views

Talk about standard synchronisation pattern on Android (SyncAdapter + Authenticator + ContentProvider). Presentation given at KrakDroid 2012 (http://www.krakdroid.pl). Video from the talk (in Polish): ...

Talk about standard synchronisation pattern on Android (SyncAdapter + Authenticator + ContentProvider). Presentation given at KrakDroid 2012 (http://www.krakdroid.pl). Video from the talk (in Polish): http://www.youtube.com/watch?v=8Oti4qf7P84.

Statistics

Views

Total Views
3,994
Views on SlideShare
3,343
Embed Views
651

Actions

Likes
12
Downloads
88
Comments
0

23 Embeds 651

http://moin.neocoin.net 418
http://porcupineprogrammer.blogspot.com 141
http://porcupineprogrammer.blogspot.in 26
http://porcupineprogrammer.blogspot.co.uk 12
http://porcupineprogrammer.blogspot.ru 7
http://porcupineprogrammer.blogspot.de 5
http://localhost 5
http://porcupineprogrammer.blogspot.fr 5
http://porcupineprogrammer.blogspot.nl 5
http://porcupineprogrammer.blogspot.com.es 4
http://porcupineprogrammer.blogspot.kr 3
http://porcupineprogrammer.blogspot.be 2
http://porcupineprogrammer.blogspot.ie 2
http://porcupineprogrammer.blogspot.com.br 2
http://porcupineprogrammer.blogspot.dk 2
http://porcupineprogrammer.blogspot.com.ar 2
http://porcupineprogrammer.blogspot.cz 2
http://porcupineprogrammer.blogspot.mx 2
http://porcupineprogrammer.blogspot.co.il 2
http://porcupineprogrammer.blogspot.jp 1
http://porcupineprogrammer.blogspot.pt 1
http://porcupineprogrammer.blogspot.sk 1
http://porcupineprogrammer.blogspot.hk 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Sync on Android Sync on Android Presentation Transcript

    • Sync ON ANDROIDJerzy Chalupskichalupjerzy@futuresimple.com
    • What we do in general...
    • What we do ALL THE TIME sync, sync, sync, sync
    • Sync ON ANDROID OVERVIEW ARCHITECTURECONTENT PROVIDER PITFALLS & PROTIPS
    • Sync ON ANDROID OVERVIEW ARCHITECTURECONTENT PROVIDER PITFALLS & PROTIPS
    • Not exactly the fresh topic... „Developing Android REST client applications” by Virgil Dobjanschi @Google I/O 2010
    • Not exactly the fresh topic... „Synchronizacja danych z serwisami webowymi w Androidzie” by Bartosz Filipowicz @KrakDroid 2011
    • Not exactly the fresh topic... „Synchronizacja danych z serwisami webowymi w Androidzie” by Bartosz Filipowicz @KrakDroid 2011 ...but there is still much confusion
    • AccountManager SyncManager UI AuthenticatorContentProvider SyncAdapter ContentResolver
    • „Wat? Why do I need to writeall this crap, sync is justfetching data from server” typical reaction
    • Sync provides data sharing
    • Sync provides data sharing offline mode
    • Sync provides data sharing offline mode responsive UI
    • Sync provides data sharing offline mode responsive UI GREAT UX
    • Sync ON ANDROID OVERVIEW ARCHITECTURECONTENT PROVIDER PITFALLS & PROTIPS
    • ContentProvider 101: CRUD CREATE insert() READ query() UPDATE update() DELETE delete()
    • ContentProvider 101: URI content://com.futuresimple.krakdroid.Provider/datasets/1
    • ContentProvider 101: URI content://com.futuresimple.krakdroid.Provider/datasets/1
    • ContentProvider 101: URI content://com.futuresimple.krakdroid.Provider/datasets/1
    • ContentProvider 101: URI content://com.futuresimple.krakdroid.Provider/datasets/1
    • ContentProvider 101: notifications content://com.futuresimple.krakdroid.Provider/datasets/1 content://com.futuresimple.krakdroid.Provider/solutions content://com.futuresimple.krakdroid.Provider/solutions/1 content://com.futuresimple.krakdroid.Provider/solutions/1/answers/1 content://com.futuresimple.krakdroid.Provider/solutions/1/answers/2 content://com.futuresimple.krakdroid.Provider/solutions/2/answers/1
    • ContentProvider 101: notifications content://com.futuresimple.krakdroid.Provider/datasets/1 content://com.futuresimple.krakdroid.Provider/solutions content://com.futuresimple.krakdroid.Provider/solutions/1 content://com.futuresimple.krakdroid.Provider/solutions/1/answers/1 content://com.futuresimple.krakdroid.Provider/solutions/1/answers/2 content://com.futuresimple.krakdroid.Provider/solutions/2/answers/1 ContentResolver.notifyChange(“content:// com.futuresimple.krakdroid.Provider/datasets/1”);
    • ContentProvider 101: notifications content://com.futuresimple.krakdroid.Provider/datasets/1 content://com.futuresimple.krakdroid.Provider/solutions content://com.futuresimple.krakdroid.Provider/solutions/1 content://com.futuresimple.krakdroid.Provider/solutions/1/answers/1 content://com.futuresimple.krakdroid.Provider/solutions/1/answers/2 content://com.futuresimple.krakdroid.Provider/solutions/2/answers/1 ContentResolver.notifyChange(“content:// com.futuresimple.krakdroid.Provider/solutions/1/answers/1”);
    • Sync ON ANDROID OVERVIEW ARCHITECTURECONTENT PROVIDER PITFALLS & PROTIPS
    • AccountManager SyncManager UI AuthenticatorContentProvider SyncAdapter ContentResolver
    • Authenticator Sync architecture CREATING NEW ACCOUNTAccountManager addAccount() UI SyncManager ContentResolver SyncAdapter ContentProvider
    • Authenticator Sync architecture CREATING NEW ACCOUNT addAccount()AccountManager addAccount() UI SyncManager ContentResolver SyncAdapter ContentProvider
    • Authenticator Sync architecture CREATING NEW ACCOUNT addAccount()AccountManager addAccount() UI SyncManager ContentResolver SyncAdapter ContentProvider
    • Authenticator Sync architecture SHOW SYNCED DATAAccountManager UI query() SyncManager ContentResolver query() SyncAdapter ContentProvider
    • Authenticator Sync architecture REQUEST SYNCAccountManager getAccountsByType() UI SyncManager ContentResolver SyncAdapter ContentProvider
    • Authenticator Sync architecture REQUEST SYNCAccountManager getAccountsByType() UI requestSync() SyncManager ContentResolver SyncAdapter ContentProvider
    • Authenticator Sync architecture REQUEST SYNCAccountManager getAccountsByType() UI requestSync() SyncManager ContentResolveronPerformSync() SyncAdapter ContentProvider
    • Authenticator Sync architecture EDIT DATAAccountManager UI insert() SyncManager ContentResolver insert() SyncAdapter ContentProvider
    • Authenticator Sync architecture EDIT DATAAccountManager UI insert() SyncManager ContentResolver notifyChange() insert() SyncAdapter ContentProvider
    • Authenticator Sync architecture EDIT DATAAccountManager UI insert() SyncManager ContentResolver notifyChange() insert() SyncAdapter ContentProvider
    • Authenticator Sync architecture EDIT DATAAccountManager getAccountsByType() UI insert() SyncManager ContentResolver notifyChange() insert() SyncAdapter ContentProvider
    • Authenticator Sync architecture EDIT DATAAccountManager getAccountsByType() UI insert() SyncManager ContentResolveronPerformSync() notifyChange() insert() SyncAdapter ContentProvider
    • Authenticator Sync architecture POST NEW DATAAccountManager UI SyncManager ContentResolveronPerformSync() SyncAdapter ContentProvider
    • Authenticator Sync architecture POST NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolveronPerformSync() SyncAdapter ContentProvider
    • Authenticator Sync architecture POST NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolver query()onPerformSync() query() SyncAdapter ContentProvider
    • Authenticator Sync architecture POST NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolver query()onPerformSync() query() SyncAdapter POST ContentProvider
    • Authenticator Sync architecture GET NEW DATAAccountManager UI SyncManager ContentResolveronPerformSync() SyncAdapter ContentProvider
    • Authenticator Sync architecture GET NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolveronPerformSync() SyncAdapter ContentProvider
    • Authenticator Sync architecture GET NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolveronPerformSync() SyncAdapter GET ContentProvider
    • Authenticator Sync architecture GET NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolver applyBatch()onPerformSync() applyBatch() SyncAdapter GET ContentProvider
    • Authenticator Sync architecture GET NEW DATA getAuthToken()AccountManager UI SyncManager ContentResolver applyBatch()onPerformSync() notifyChange() applyBatch() SyncAdapter GET ContentProvider
    • Authenticator Sync architecture GET NEW DATA getAuthToken()AccountManager onLoaderFinished() UI SyncManager ContentResolver applyBatch()onPerformSync() notifyChange() applyBatch() SyncAdapter GET ContentProvider
    • Authenticator Sync architecture WIN #1: NO REMOTE I/O IN UIAccountManager UI SyncManager ContentResolver SyncAdapter ContentProvider
    • Authenticator Sync architecture WIN #2: SYNC SCHEDULINGAccountManager UI SyncManager ContentResolver SyncAdapter ContentProvider
    • Sync ON ANDROID OVERVIEW ARCHITECTURECONTENT PROVIDER PITFALLS & PROTIPS
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/1
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/1 Plan A: Use local IDs! (BaseColumns._ID)
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/1 Plan A: Use local IDs! (BaseColumns._ID) ISSUE: still need server-side IDs for relations
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/1 Plan A: Use local IDs! (BaseColumns._ID) ISSUE: still need server-side IDs for relations ISSUE: conversions between server and local IDs
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/15002900 Plan B: OK, use server-side IDs!
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/15002900 Plan B: OK, use server-side IDs! ISSUE: what about offline mode?
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/-42 content://com.futuresimple.krakdroid.Provider/datasets/15002900 Plan C: OK, let’s mix things up!
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/-42 content://com.futuresimple.krakdroid.Provider/datasets/15002900 Plan C: OK, let’s mix things up! ISSUE: very tricky implementation
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/GUID Plan D: GUID
    • IDs in ContentProvider URIs content://com.futuresimple.krakdroid.Provider/datasets/GUID Plan D: GUID ISSUE: needs support on the backend
    • ContentResolver requestSync() vs. notifyChange() requestSync(account, authority, extras) notifyChange(uri, observer, syncToNetwork)
    • ContentResolver requestSync() vs. notifyChange() requestSync(account, authority, extras) notifyChange(uri, observer, syncToNetwork)
    • Deleting an account From your app From system settings From 3rd party app
    • Deleting an account From your app “Where should I From system settings perform user data cleanup?” From 3rd party app
    • Deleting an account @Override getAccountRemovalAllowed()
    • Deleting an account @Override getAccountRemovalAllowed() CONS: depends on current Settings implementation. PROS: exactly the thing you need.
    • Deleting an account <receiver android:name=".auth.AccountBroadcastReceiver" android:enabled="true" > <intent-filter> <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" /> </intent-filter> </receiver>
    • Deleting an account <receiver android:name=".auth.AccountBroadcastReceiver" android:enabled="true" > <intent-filter> <action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED" /> </intent-filter> </receiver> CONS: only info about existing accounts. PROS: peace of mind.
    • Sync lifecycle Happy case:
    • Sync lifecycle Happy case: requestSync()
    • Sync lifecycle Happy case: onPerformSync() requestSync()
    • Sync lifecycle Happy case: onPerformSync() requestSync() onStatusChanged()
    • Sync lifecycle Not-so-happy case: onPerformSync() requestSync() onStatusChanged()
    • Sync lifecycle Not-so-happy case: onPerformSync() requestSync() onStatusChanged()
    • Sync lifecycle Not-so-happy case: onPerformSync() requestSync() cancelSync() + onStatusChanged()
    • Futureproof your sync
    • Futureproof your sync 1. Be lenient on GET
    • Futureproof your sync 1. Be lenient on GET 2. Be strict on POST
    • Futureproof your sync 1. Be lenient on GET 2. Be strict on POST 3. Have resync in v1.0
    • ?
    • Thanks.