mdevcon - a primer to syncadapters

42
A PRIMER TO SYNC ADAPTERS Kiana Tennyson mdevcon Tuschinski Theater March 2013

Upload: kiana-tennyson

Post on 15-Jul-2015

2.627 views

Category:

Technology


0 download

TRANSCRIPT

A PRIMER TO SYNC ADAPTERS

Kiana Tennyson

mdevcon

Tuschinski Theater

March 2013

OVERVIEW

v Who is Kiana?

v SyncAdapter Use Cases

v The Big Picture

v Configuration

v Authorization, Content, Synchronization

v Wrap up/Questions

WHO’S KIANA?

v Software Developer

v Professional background working on web portals

v Work at Manheim, wholesale vehicle auction company

v Customer facing applications •  Web portal (www.manheim.com) Ruby, Java, JS •  iOS app •  Android app

SYNC ADAPTERS ARE…?

v Share data between a remote data source and an Android

device

v Android OS provides plug-in architecture that takes care of: •  Coordinating network availability with syncing all datasources •  Scheduling synchronization/Handling stopped processes •  Accommodating user preferences when syncing •  Handling network interruptions

TOUGH PARTS

v Good news! Writing a Custom SyncAdapter is actually easy!

v Bad news. There are potentially tough parts: •  Authentication Handling •  (Custom) Content Provider •  Data Handling

v Defined by business rules

BEST USE CASES

Application that…

v Requires authentication step to connect to remote

datasource

v Potentially could use a built-in ContentProvider •  All providers found in android.provider package

v Application Suite backed by custom ContentProvider

! (BEST USE CASES)

v Anything that DOES NOT require a login

v Any source that provides an RSS feed •  Typically public data sources like news/media sites •  Write a parser that reads the feed only when the user wants it •  SyncAdapter not necessary to write to the ContentProvider

v If Service does not constantly need to run in the

background •  User has limited battery power, code with this in mind

CONFIGURATION

A Primer to SyncAdapters

THE BIG PICTURE

AccountManager

• Requires Authentication Service to add Account

• Adds Account to Account List

SyncManager

• Uses Account List as a basis for it’s Sync List

• Requires Sync Service to start data syncs

ContentProvider

•  Holds the data •  Called in

onPerformSync()

AUTHENTICATION

v Write an AuthActivity •  serves UI for user to enter account info •  Write it to complete the authorization process

v Write an Authenticator •  MUST extend AbstractAccountAuthenticator •  Returns the AuthActivity in a Bundle object

v Write an Authentication Service •  MUST extend Service •  onBind return IBinder for the Authenticator

SYNCHRONIZATION

v Write a SyncAdapter •  MUST extend AbstractThreadedSyncAdapter •  Overwrite onPerformSync()

v Write a Sync Service •  MUST extend Service •  Allow creation of ONE SyncAdapter •  onBind returns a IBinder for SyncAdapter

RESOURCE XMLS

v Provide configuration info

v Map account type to objects •  SyncAdapter and Authenticator are connected via

android:accountType

v Map content authority to SyncAdapter

RESOURCE XMLS

<?xml version="1.0" encoding="utf-8"?>!

<account-authenticator xmlns:android="http://

!schemas.android.com/apk/res/android”!

android:accountType=”your.uniquename.here"!

android:icon="@drawable/icon"!

android:smallIcon="@drawable/icon"!

android:label="@string/label"!

/>!

Add Account

v Notice result of android:icon

v Green lights – Account added

v Gray lights – Account not added

v  Clicking one launches Auth

Activity interface

RESOURCE XMLS

<?xml version="1.0" encoding="utf-8"?>!

<sync-adapter xmlns:android="http://

!schemas.android.com/apk/res/android”!

android:contentAuthority="com.android.contacts"!

android:accountType="your.uniquename.here"!

android:supportsUploading="false"!

android:userVisible="true"!

/>!

MANIFEST

v Several appropriate permissions

v Declare AuthenticationService with <service> tag •  Intent filter: “android.accounts.AccountAuthenticator” •  Meta-data tag points AccountAuthenticator to xml resource file

v 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

v Declare AuthActivity (no Intent filter necessary)

MANIFEST.XML

<service android:name=".authenticator.AuthenticationService” !android:exported="true”>!

<intent-filter>!

<action android:name="android.accounts.AccountAuthenticator" />! </intent-filter>! <meta-data android:name="android.accounts.AccountAuthenticator”!

!android:resource="@xml/authenticator" />!

</service>!<service android:name=".syncadapter.SyncService” android:exported="true">! <intent-filter>!

<action android:name="android.content.SyncAdapter" />! </intent-filter>! <meta-data android:name="android.content.SyncAdapter”!

!android:resource="@xml/syncadapter" />!

<meta-data android:name="android.provider.CONTACTS_STRUCTURE”!!android:resource="@xml/contacts" />!

</service>!

WHY SERVICES?

v SyncAdapter is bound to a service, Authentication is bound to a

service… but why?

v SyncManager finds all syncAdapters via a SyncAdaptersCache.

v AccountManager finds all Accounts via AccountAuthenticatorCache

v RegisteredServicesCache •  Reads the XML files created (account-authenticator and syncadapter) •  Generates service maps

CODE SUMMARY

v Create a syncadapter.xml file

v Create an authenticator.xml file

v Add an authentication <service> to manifest

v Add a sync <service> to manifest

v Add correct permissions to manifest

v Write some java… but what does any of this mean?

THE DATA

A Primer to SyncAdapters

ACCESSING CONTENT

The Device User Android Application(s)

Context

ContentResolver

ContentProviderClient

ContentProvider

Data Storage •  SharedPreferences •  External Storage •  SQLLiteDatabase

CONTENT PROVIDER

v Manages central repository of data.

v SyncAdapters wouldn’t exist without ContentProviders •  SyncAdapter mentioned in ContentProvider section of API

Guide

v Built in ContentProviders contain a SyncState table •  Use to store sync state, meta-data or any sync related data

v Sync related columns in other tables: •  DIRTY, VERSION, SOURCE_ID

IMPORTANT COLUMNS

v 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

v VERSION •  Incremented by Provider whenever the data row is changed. •  High-water marking (aka lastSyncState)

v 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 remote

source

CUSTOM CONTENT PROVIDER

v 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

v These properties should be applied to Custom SyncAdapter

v Thread safe

v Many calls to many

ContentAuthorities (CA)

v Expensive call (Many CA lookups)

v Resolver contains a Client

v Not thread safe

v Repeated calls to same CA

v Cheaper call (one CA lookup)

v You MUST call release() to avoid

memory leak

CONTENT RESOLVER VS CONTENTPROVIDER CLIENT

ContentResolver ContentProviderClient

CONTENTPROVIDER CLIENT

v Part of onPerformSync() method signature.

v Not thread safe, so be careful with usage •  Utilize locking strategies, ensure no outside services are

performing activities on sync-candidate data

v Android Sample project uses threadsafe ContentResolver

via a Manager

CONTENT RESOLVER

v Do I really need this? Your choice. •  ContentResolvers query the ContentProvider •  Use it to CRUD data inside syncAdapter.onPerformSync(); •  SampleSyncAdapter uses the ContentResolver by way of it’s

ContactsManager class, because it performs batch operations

v Retrieve it using: context.getContentResolver();

v However, there are other ways to access the data

DATA CONSIDERATIONS

v Determine structure of serialized/transmitted data •  Using json? xml? yaml? •  What does a single row (data unit) look like?

v How does the server parse and save the transmitted data? •  Likely defined by business limitations.

v How does the device parse/save the data? •  ContentProviderClient or ContentResolver (batch ops)

AUTHENTICATION

A Primer to SyncAdapters

ACCOUNT

v Account object contains an Account name and Account type. •  Note, the Account object does NOT contain a password •  Example: user has multiple twitter accounts

v AccountManager maps an Account object to it’s “password”

v Recommended strategy: store Account and authToken on device •  SampleSyncAdapter project stores password (possible human error)

v SyncManager can only schedule syncs per Account

ACCOUNT MANAGER

v Contains centralized registry of user’s online accounts

v Used to determine list of data sources to be synced •  AccountManager provides list of Accounts •  SyncManager grabs the list of Accounts for syncing

v AccountAuthenticatorCache maps accountType to objects

extending AbstractAccountAuthenticator

v Android Component; you don’t write this

AUTHENTICATION

v User chooses to Add an Account •  List compiled from array of allowable account types

v System chooses Authenticator based on

“android:accountType” •  Binds to a Service which returns the Authenticator’s IBinder

v Authenticator’s overridden addAccount() method is called •  Ultimately the Login UI displays, new Account is created

AUTHENTICATOR

v Allows developer to implement authentication •  Per remote service

v Must extend AbstractAccountAuthenticator •  Responds to an intent “android.accounts.AccountAuthenticator”

advertised by the AccountManager for it’s accountType only.

v Authentication Service returns a Binder to your implemented

AbstractAccountAuthenticator

v addAccount() returns bundle with intent containing Activity

ADD ACCOUNT Sample SyncAdapter Activity Example Activity

THE SYNC

A Primer to SyncAdapters

SYNCMANAGER

v Responsible for scheduling, cancelling syncs. •  Maintains a list of active syncs (mActiveSyncContext)

v Sync handling strategy very tightly coupled to Accounts •  Account is part of most SyncManager methods

v How do the SyncHandler and Account interact? •  SyncHandler receives a message containing an

ActiveSyncContext. ActiveSyncContext contains all information about the sync that needs to begin including the Account.

SYNCHRONIZATION

v SyncManager contains ONE SyncHandler

v SyncHandler’s job: receive/handle sync operation messages •  On receiving a Connection Message, calls startSync for the

syncAdapter in question •  startSync() spins up a new SyncThread •  The method onPerformSync() that was implemented is

invoked when run() is invoked on the thread

SYNC ADAPTER

v Where the main party happens. The method onPerformSync()

gets called within a syncThread.run()

v Make use of the DIRTY/VERSION/SOURCE_ID rows

v Instantiate like any class. •  However, create only one for thread safety.

ONPERFORMSYNC()

v What should I do in the onPerformSync() method?

v Merge remote data with local data •  DIRTY/VERSION/SOURCE_ID columns

v Use business rules to determine order of operations •  Whether local data overwrites remote data or vice versa

v Implement a remote connection strategy to access remote

data

DEV TOOLS

WRAP UP

v We learned… •  What SyncAdapters are •  Set up •  Content (ContentProvider/data characteristics) •  Authorization (Accounts, Account Management) •  Synchronization (SyncManager, SyncService) •  Debugging/Dev Tools

QUESTIONS?

A Primer to SyncAdapters