Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android SyncAdapter

Android SyncAdapter

Presented at DaFED Meetup #23

Introduction to SyncAdapter API in Android with an overview of possible use cases.

Nemanja Nedic

July 02, 2014
Tweet

More Decks by Nemanja Nedic

Other Decks in Programming

Transcript

  1. Optimize data transfer timing “A good app is like a

    good butler. It has what you want before you have to ask for it.”
  2. Optimizing network traffic Minimize the number of the radio state

    transitions Prefetch data for the next 2-5 minutes (1-5 MB) Batch all non-time critical transfers Bundle non-time critical with critical transfers Eliminate client-side pooling
  3. SyncAdapter advantages Automated execution Failed transfer queuing Built in connectivity

    checking Simplified app data transfer bundling and batching Cross device batching and bundling
  4. Implementing a SyncAdapter public class SyncAdapter extends AbstractThreadedSyncAdapter { public

    SyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); } public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) super(context, autoInitialize, allowParallelSyncs); } @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { //Synchronize your data between client and server } }
  5. SyncAdapter service public class SyncService extends Service { private static

    final Object sSyncAdapterLock = new Object(); private static SyncAdapter sSyncAdapter = null; @Override public void onCreate() { synchronized (sSyncAdapterLock) { if (sSyncAdapter == null) { sSyncAdapter = new SyncAdapter(getApplicationContext(), true); } } } @Override public IBinder onBind(Intent intent) { return sSyncAdapter.getSyncAdapterBinder(); } }
  6. Account authenticator public class AccountAuthenticator extends AbstractAccountAuthenticator { public static

    final String ACCOUNT_TYPE = "rs.dcsw.syncadapterdemo"; public static final String ACCOUNT_NAME = "STUB ACCOUNT"; private final Context mContext; public AccountAuthenticator(Context context) { super(context); mContext = context; } @Override public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { AccountManager manager = AccountManager.get(mContext); final Account account = new Account(ACCOUNT_NAME, ACCOUNT_TYPE); return null; } ... }
  7. Account authenticator service public class AuthenticationService extends Service { private

    AccountAuthenticator mAccountAuthenticator; @Override public void onCreate() { mAccountAuthenticator = new AccountAuthenticator(this); } @Override public IBinder onBind(Intent intent) { return mAccountAuthenticator.getIBinder(); } }
  8. Stub content provider public class SyncContentProvider extends ContentProvider { public

    static final String AUTHORITY = "rs.dcsw.syncadapterdemo.provider"; @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } ... }
  9. Triggering a sync When server data changes When device (client)

    data changes On demand When the system sends out a network message At regular intervals
  10. Triggering a sync private void requestSyncAutomatically() { final Account account

    = new Account(AccountAuthenticator.ACCOUNT_NAME, AccountAuthenticator.ACCOUNT_TYPE); ContentResolver.setSyncAutomatically(account, SyncContentProvider.AUTHORITY, true); }
  11. Triggering a sync private void onDemandSync() { final Account account

    = new Account(AccountAuthenticator.ACCOUNT_NAME, AccountAuthenticator.ACCOUNT_TYPE); ContentResolver.requestSync(account, SyncContentProvider.AUTHORITY, null); }
  12. Triggering a sync private void requestPeriodicSync() { final Account account

    = new Account(AccountAuthenticator.ACCOUNT_NAME, AccountAuthenticator.ACCOUNT_TYPE); long interval = 60 * 60; // one hour ContentResolver.addPeriodicSync(account, SyncContentProvider.AUTHORITY, null, interval); }