Question

My app uses a SyncAdapter to periodically sync server data with SQLite. It also syncs this data in response to a GCM message that indicates new/updated server data; via. an IntentService.

These components each do their work in different background threads and are created by different system processes (SyncManager/GCM broadcast) and have different lifecycles; unpredictably!

What is the best approach to fault-tolerantly co-ordinate these components: e.g.

  • for an Activity to signal to each that they should do no work
  • to signal to the SyncAdapter to do no work when the GCM IntentService is working, and vice versa.
Was it helpful?

Solution

You should

  1. Put all your syncing code into the SyncAdapter
  2. Remove the IntentService
  3. In the GcmBroadcastReceiver you start the SyncAdapter instead of the IntentService.

Below is example code copied from the SyncAdapter documentation.

public class GcmBroadcastReceiver extends BroadcastReceiver {
    ...
    // Constants
    // Content provider authority
    public static final String AUTHORITY = "com.example.android.datasync.provider"
    // Account type
    public static final String ACCOUNT_TYPE = "com.example.android.datasync";
    // Account
    public static final String ACCOUNT = "default_account";
    // Incoming Intent key for extended data
    public static final String KEY_SYNC_REQUEST =
        "com.example.android.datasync.KEY_SYNC_REQUEST";
    ...
    @Override
    public void onReceive(Context context, Intent intent) {
        // Get a GCM object instance
        GoogleCloudMessaging gcm =
            GoogleCloudMessaging.getInstance(context);
            // Get the type of GCM message
        String messageType = gcm.getMessageType(intent);
        /*
         * Test the message type and examine the message contents.
         * Since GCM is a general-purpose messaging system, you
         * may receive normal messages that don't require a sync
         * adapter run.
         * The following code tests for a a boolean flag indicating
         * that the message is requesting a transfer from the device.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)
            &&
            intent.getBooleanExtra(KEY_SYNC_REQUEST)) {
            /*
             * Signal the framework to run your sync adapter. Assume that
             * app initialization has already created the account.
             */
            ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
            ...
        }
        ...
    }
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top