Depende muito de que tipo de sincronização você precisa.
Periódico
Se seu aplicativo for um aplicativo de notícias que publica postagens em um determinado horário todos os dias (digamos às 7h45 todos os dias), você executa uma tarefa periódica em um serviço em segundo plano, às 8h.
por exemplo : Drippler. Eles me notificam uma vez por dia (por volta das 18h30). Eu acredito que eles usam uma tarefa periódica.
Evento desencadeado
Se sua transferência de dados for acionada pela ação do usuário, use um serviço em segundo plano ou um AsyncTask para a transferência de dados.
por exemplo : DropBox / Evernote. Eles são sincronizados quando interajo com o aplicativo.
Instantâneo
Se o seu aplicativo executar mensagens importantes / e-mails / atualizações importantes não periódicas , você precisará de notificações por push, porque deseja alertar o usuário imediatamente. Use GCM ou Parse para este caso. por exemplo: WhatsApp / bate-papo do Google. Como você mencionou explicitamente que não deseja usar o GCM, explicarei por que você deve usar um provedor de notificação por push padrão em vez de escrever o seu:
As notificações por push funcionam instantaneamente - há muito pouco atraso (na ordem de segundos, raramente minutos). Se você implementasse sua própria solução / biblioteca para fazer isso - em um modelo ingênuo, você executaria ping no servidor a cada segundo ou 5 segundos ou um minuto para verificar o status. Isso é muito ineficiente, pois consome CPU (e, portanto, bateria), largura de banda no celular e carga no servidor. No entanto, no GCM / Parse, eles sempre mantêm uma porta aberta com o servidor (veja aqui ). Esta é a maneira padrão e mais eficiente. Além disso, se 10 aplicativos usam o GCM, você não precisa de 10 conexões abertas, apenas uma por dispositivo. E você realmente não deseja desenvolver sua própria solução, a menos que tenha uma razão / fundos / tempo válidos para fazê-lo.
Uma observação sobre o adaptador de sincronização : o adaptador de sincronização funciona bem nos três casos acima. Verifique Executando um adaptador de sincronização e você verá que ele depende do GCM ou de seu próprio mecanismo (gatilho de evento ou solução personalizada) ou disponibilidade de rede (gatilho de evento) ou evento periódico. Em suma, esta é uma boa classe conveniente para sincronizar dados sem ter que fazer uma longa lista de inicializações todas as vezes ou implementar todos os casos acima em um só lugar.