Android 101: Services, AsyncTasks e Notifications

As AsyncTasks servem para executar operações em segundo plano sem congelar a thread UI principal.

AsyncTasks

As AsyncTask são semelhantes a threads, no entanto são mais simples de usar, porque não é necessário manipular threads ou handlers. A AsyncTask permite a execução de operações em segundo plano, sem bloquear a thread UI principal, no entanto pode manipular elementos do interface a partir da AsyncTask.

Para implementar uma AsyncTask precisa criar uma subclasse desta e fazer override dos seus métodos, sendo o método de maior relevo o doInBackground(Params. ..). Como o nome deste método indica, ele irá executar um trecho de código em segundo plano.

Na nossa aplicação necessitamos carregar o stream de Buzzes através da rede. A melhor maneira de o fazer é através de uma AsyncTask. Isto libertará a thread principal da aplicação, o que evita o bloqueio da interface do utilizador ou, num caso pior, o sistema lançar um aviso ao utilizador para matar a aplicação porque esta não se encontra a responder. Veja mais detalhes de como desenhar a sua aplicação para dar uma resposta mais imediata.

Um exemplo de como usar a AsyncTask retirado da nossa aplicação:

class LoadBuzzes extends AsyncTask<Void, Void, ArrayList< Buzz>> {
    @Override
    protected void onPreExecute() {
        getHoneybuzzActivity().showProgress(); // show loading screen
    }

    @Override
    protected ArrayList<Buzz> doInBackground(Void... params) {
        try {
            // we’re caching the data so we’ll check if we need to update it from the server or just load from cache
            boolean refresh = Buzz.getUpdateChachedBuzzes(getActivity());
            Buzz.setUpdateChachedBuzzes(getActivity(), false);
            return Buzz.getBuzzes(getBuzz(), getActivity(), refresh);
        }
        catch (Exception e) {
            handleException(e);
            return null;
        }
    }

    @Override
    protected void onPostExecute(ArrayList< Buzz> feed) {
        getHoneybuzzActivity().hideProgress(); // hide loading screen
        if (feed != null) {
            try {
                // load buzzes list onto the UI
            }
            catch(Exception e) {
                Logging.e("Error loading buzzes", e);
            }
        }
    }
}

Esta tarefa é lançada da seguinte forma:

new LoadBuzzes().execute();

Services

Um Service é um componente que representa tanto a intenção de uma aplicação executar uma operação de longa duração enquanto não interage com o utilizador ou fornecer funcionalidades para outras aplicações usarem.

Para verificar se existem actualizações no stream do Buzz usamos um Service que corre em segundo plano. Quando actualizações são encontradas, o Service mostra uma notificação. Estes são os trechos de código mais importantes na nossa classe de sincronização:

private Timer mTimer = new Timer();
private NotificationManager mNM;

@Override
public void onCreate() {
    mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

    // the time interval between checks is saved in the app’s preferences
    SharedPreferences prefs = HoneybuzzApplication.getSharedPreferences();
    int intervalMinutes = Integer.parseInt(prefs.getString(HoneybuzzApplication.PREFERENCE_INTERVAL, String.valueOf(30)));
    int intervalMiliseconds = intervalMinutes * 60 * 1000;
    mTimer.schedule(mUpdateTask, intervalMiliseconds, intervalMiliseconds);
}

private TimerTask mUpdateTask = new TimerTask() {
    @Override
    public void run() {
        try {
            String lastUpdated = com.quasibit.honeybuzz.Buzz.getLastUpdated(getApplicationContext());
            String serverUpdate = com.quasibit.honeybuzz.Buzz.getServerUpdated(HoneybuzzApplication.buzz, getApplicationContext());

            // check if the last update to the server is the same as the last update available in cache
            if (!lastUpdated.equals(serverUpdate)) {
                Buzz.getBuzzes(HoneybuzzApplication.buzz, getApplicationContext(), true);

                // after the updates are loaded the user gets a notification
                showNotification();
            }
        }
        catch(Exception e) {
            Logging.e(e);
        }
    }
};

Aqui encontram um bom artigo com a comparação entre AsyncTask, Service, Thread, e IntentService.

Notificações

Uma notificação é uma mensagem que aparecerá na barra de status do sistema alertando o utilizador sobre algo que ele deve saber. A sua implementação é muito simples.

No caso da nossa aplicação, notificamos o utilizador sempre que encontrarmos actualizações no seu stream do Buzz. Veja como lançamos a nossa notificação:

private NotificationManager mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

private void showNotification() {
    String msg = getApplicationContext().getString(R.string.notif_buzzupdates);
    Notification notification = new Notification(R.drawable.ic_launcher_honeybuzz, msg, System.currentTimeMillis());
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, HoneybuzzListActivity.class), 0);
    notification.setLatestEventInfo(this, getApplicationContext().getString(R.string.app_name), msg, contentIntent);
    mNM.notify(NOTIFICATION, notification);
}

Opcionalmente pode adicionar à sua notificação uma mensagem, um som de alerta, vibração e/ou piscar de LED.

Artigos relacionados