24

I have been seeing two implementations for syncing data between the server and the client on majority of the apps. This assumes no GCM is set up:-

  1. Running an intent service periodically which downloads the data from the network and stores in the database.
  2. Implementing a Sync Adapter which runs periodically.

Which of the above would you recommend to have in your app and why?

Rasmus
  • 823
  • 2
  • 7
  • 15

6 Answers6

18

It heavily depends on what kind of syncing you need.

Periodic

If your app is a news app that publishes posts at a certain time every day(lets say at 7.45 AM every day), then you run a periodic task in a background service, say at 8 AM.

e.g.: Drippler. They notify me once every day(around 6.30 PM). I believe they use a periodic task.

Event Triggered

If your data transfer is triggered by user action, then use a background service or an AsyncTask for the data transfer.

e.g.: DropBox/Evernote. They sync when I interact with the app.

Instantaneous

If your app runs instant messaging/mails/non-periodic important updates, then you need push notifications, because you want to alert the user immediately. Use either GCM or Parse for this case. e.g: WhatsApp/Google chat. Since you explicitly mentioned you don't want to use GCM, I will tell why you should use a standard push notification provider instead of writing your own:

Push notifications work instantaneously - there is very little delay(in the order of seconds, rarely minutes). If you were to implement your own solution/library for doing this - in a naive model, you would ping the server every second or 5 seconds or a minute to check for the status. This is very inefficient as it consumes CPU(and hence battery), bandwidth on the mobile and load on your server. However, in GCM/Parse, they always keep a port open with the server(see here). This is the standard and most efficient way. Plus, if 10 apps use GCM, you don't need 10 open connections, you only need one per device. And you really don't want to develop your own solution unless you have a valid reason/funds/time to do so.

A note on Sync Adapter: Sync Adapter works well for all the above three cases. Check Running a Sync Adapter and you will see that it either depends on GCM or your own mechanism(event trigger or custom solution) or network availability(event trigger) or periodic event. All in all, this is a good convenient class for syncing data without having to do a long list of initializations every time or to implement all the above cases at one place.

Sundeep
  • 607
  • 3
  • 9
  • As an extended question,if i need to update live scores of a match, is instantaneous scenario the right one for this context? I have a screen having match details and while the user is on that screen, scores should automatically get updated without syncing or manual update. So would gcm be the right step ahead? – gaara87 Feb 23 '14 at 18:26
  • @AkashRamani I don't see a reason why you shouldn't use GCM/Parse for this case. However, GCM is free while Parse bills you beyond a certain point. If your updates are well within 4096 bytes, then you can send the update directly. If your score updates are very frequent, then polling might be a good idea instead of GCM(say, for cricket scores). I would suggest to test/profile both polling and GCM for latency and CPU/battery consumption. – Sundeep Feb 24 '14 at 14:06
  • AWS also has a notification solution that is cross platform and cross market. See: http://docs.aws.amazon.com/sns/latest/dg/SNSMobilePush.html – Brill Pappin Mar 11 '14 at 16:15
12

Note: Sync adapters run asynchronously, so you should use them with the expectation that they transfer data regularly and efficiently, but not instantaneously. If you need to do real-time data transfer, you should do it in an AsyncTask or an IntentService. - source.

Basically, if you need real time transfer use IntentService (the first option), else SyncAdapter. I prefer an IntentService though because it feels more customizable, but a more trivial approach would be to use a SyncAdapter.

3

There is one aspect of a SyncAdapter that has not been mentioned by the other answers.

The SyncAdapter pattern requires that you have a specific ContentProvider authority that you sync to and a specific account type (see Authenticator) that's going to be synced. So unless you already have those components in your architecture (e.g. because you give other apps access to your data or you need to support accounts) a SyncAdapter will cause significant implementation overhead.

Marten
  • 131
  • 1
2

When it comes to synching data which involves connectivity you'd want to be able to scale also. I believe the recommended way to go about it is using the Sync Adapter.

It also seems to be that way if you check out the Android traning guide: Creating a Sync Adapter

The sync adapter component in your app encapsulates the code for the tasks that transfer data between the device and a server. Based on the scheduling and triggers you provide in your app, the sync adapter framework runs the code in the sync adapter component...

gnat
  • 21,442
  • 29
  • 112
  • 288
2

Sync Adapters should be used unless you need real time data because, It automates data transfer based of variety of criteria, like data changes, elapsed time, time of day, etc. It centralizes all data transfers so your data transfer is done in conjunction with data transfers from other apps, which reduces battery usage.

For instantaneous tasks we can use,

AsyncTask for task that are of short duration, may be 3-4 seconds.

IntentService for long running tasks.

0

Since we're talking about design, we should mention managing SyncAdapters, the SyncResult object, and what happens after.

I actually use a SyncAdapter to tell my library to make IntentService web calls to my server. Managing this "sync" operation is tricky.

One approach I am now taking is to completely forgo the SyncResult object and just use a service to log the outcomes of each individual "Sync"

Saik Caskey
  • 101
  • 1