What’s a Sync Adapter?• Transfers data to/from Android phone to remote datasource
What’s a Sync Adapter?• Plug-in Architecture• Coordinates Network Availability with syncing• Gracefully handles Network Interruptions• Schedules synchronization• Handles stopped processes• Accommodates user preferences
Good News!• Writing a Custom SyncAdapter is actuallypretty easy!
Sad News…• You will have toimplement businessrules…• Authentication Handling• (Custom) Content Provider• Data Handling
Good Use Cases• Requires Authentication Stepto connect to remote DS• Has a Custom ContentProvider• Will require a new Sync Adapter• Application Suite backed by aCustom ContentProvider• Requires non-authenticationpermissions
(Bad?) Use Cases• Does not require permissions orlogin• RSS/public data feed• Write a parser the reads the feedupon user need (poetry)• Sync Adapter not necessary towrite to a ContentProvider• If Service does not need toconstantly run in background• Conserve battery power, or user willdelete your app
The Big PictureAccountManager• RequiresAuthenticationService to addAccount• Adds Account toAccount ListSyncManager• Uses AccountList as a basisfor it’s Sync List• Requires SyncService to startdata syncsContentProvider• Holds the data• Called inonPerformSync()
Authentication• Write an AuthActivity• serves UI for user to enter account info• Write it to complete the authorization process• Write an Authenticator• MUST extend AbstractAccountAuthenticator• Returns the AuthActivity in a Bundle object• Write an Authentication Service• MUST extend Service• onBind return IBinder for the Authenticator
Synchronization• Write a SyncAdapter• MUST extend AbstractThreadedSyncAdapter• Overwrite onPerformSync()• Write a Sync Service• MUST extend Service• Allow creation of ONE SyncAdapter• onBind returns a IBinder for SyncAdapter
Manifest• Include several appropriate permissions• Declare AuthenticationService with <service> tag• Intent filter: “android.accounts.AccountAuthenticator”• Meta-data tag points AccountAuthenticator to xml resource file• Declare SyncService with <service> tag• Intent filter: “android.content.SyncAdapter”• Meta-data tag points SyncAdapter to xml resource file• Other Meta-data tag defines custom MIME-types• Declare AuthActivity (no Intent filter necessary)
Why Services?• Why do we need these <service> tags?• SyncAdapter is bound to a service, Authentication is bound to aservice… but why?• SyncManager finds all syncAdapters via a SyncAdaptersCache• AccountManager finds all Accounts via AccountAuthenticatorCache• RegisteredServicesCache• Reads the XML files created (account-authenticator and syncadapter)• Generates service maps
Code Summary• Create a syncadapter.xml file• Create an authenticator.xml file• Add an authentication <service> to manifest• Add a sync <service> to manifest• Add correct permissions to manifest• Write some java… but what does any of this mean?
Content Provider• Manages central repository of data.• SyncAdapters wouldn’t exist without ContentProviders• SyncAdapter mentioned in ContentProvider section of API Guide• Built in ContentProviders contain a SyncState table• Use to store sync state, meta-data or any sync related data• Sync related columns in other tables:• DIRTY, VERSION, SOURCE_ID
Important Columns• DIRTY (local modifications)• Indicates data row has been changed locally since last sync.• When SyncAdapter adds/updates a row, append“CALLER_IS_SYNCADAPTER” to Content URI• VERSION• Incremented by Provider whenever the data row is changed.• High-water marking (aka lastSyncState)• SOURCE_ID• Unique ID for data row (primary key on the remote datasource)• If set to null, indicates to SyncAdapter to create new row on remotesource
Custom Content Provider• What properties make the built-in ContentProviders“syncable”?• Extra “For Sync use only” table that holds metadata• “CALLER_IS_SYNCADAPTER” query param• Use of “high-water-mark” is essential• These properties should be applied to CustomSyncAdapter
Data Considerations• Determine structure of serialized/transmitted data• Using json? xml? yaml?• What does a single row (data unit) look like?• How does the server parse and save the transmitteddata?• Likely defined by business limitations.• How does the device parse/save the data?• ContentProviderClient or ContentResolver (batch ops)
Android SampleSyncAdapter• ContentProviderClient• in onPerformSync() method signature• Unused!• ContentResolver• Performs actual syncingin NetworkUtilities.java
A ComparisonContent Resolver• Thread safe• Many calls to manyContentAuthorities (CA)• Expensive call(Many CA lookups)• Resolver contains a ClientContentProviderClient• Not thread safe• Repeated calls to sameCA• Cheaper call (one CAlookup)• You MUST call release()to avoid memory leak
Account• Account object contains an Account name and Accounttype.• Note, the Account object does NOT contain a password• Example: user has multiple twitter accounts• AccountManager maps an Account object to it’s“password”• Recommended strategy: store Account and authToken ondevice• SampleSyncAdapter project stores password (possible humanerror)• SyncManager can only schedule syncs per Account
Account Manager• Contains centralized registry of user’s online accounts• Used to determine list of data sources to be synced• AccountManager provides list of Accounts• SyncManager grabs the list of Accounts for syncing• AccountAuthenticatorCache maps accountType to objectsextending AbstractAccountAuthenticator• Android Component; you don’t write this
Authentication• User chooses to Add an Account• List compiled from array of allowable account types• System chooses Authenticator based on“android:accountType”• Binds to a Service which returns the Authenticator’s IBinder• Authenticator’s overridden addAccount() method is called• Ultimately the Login UI displays, new Account is created
Add AccountSample SyncAdapter Activity Example Activity
SyncManager• Responsible for scheduling, cancelling syncs.• Maintains a list of active syncs (mActiveSyncContext)• Sync handling strategy very tightly coupled to Accounts• Account is part of most SyncManager methods• How do the SyncHandler and Account interact?• SyncHandler receives a message containing anActiveSyncContext. ActiveSyncContext contains all informationabout the sync that needs to begin including the Account.
Synchronization• SyncManager contains ONE SyncHandler• SyncHandler’s job: receive/handle sync operationmessages• On receiving a Connection Message, calls startSync for thesyncAdapter in question• startSync() spins up a new SyncThread• The method onPerformSync() that was implemented is invokedwhen run() is invoked on the thread
SyncAdapter• Where the main party happens. The methodonPerformSync() gets called within a syncThread.run()• Make use of the DIRTY/VERSION/SOURCE_ID rows• Instantiate like any class.• However, create only one for thread safety.
onPerformSync()• What should I do in the onPerformSync() method?• Merge remote data with local data• DIRTY/VERSION/SOURCE_ID columns• Use business rules to determine order of operations• Whether local data overwrites remote data or vice versa• Implement a remote connection strategy to access remotedata
User Preferences• Intended for use with Preferences Framework• Add “android:accountPreferences” to<account-authenticator>• Build Preferences resource file• Create Activity which gathers user prefs• Must extend PreferenceActivity• Noticing a pattern?