Caso prefira, você encontrará todo esse material, em inglês, no site do Developer Android. A tradução e comentários dos materiais eu faço livremente para ajudar a comunidade que fala português.

segunda-feira, 21 de março de 2011

Atividades

Uma atividade é um componente de aplicação que provê uma tela onde o usuário poderá interagir para fazer alguma coisa como discar um número, bater uma foto, enviar um email ou ver um mapa. A cada atividade é dada uma janela na qual é desenhada a interface de usuário. A janela normalmente preenche toda a tela mas pode ser menor que a tela e flutuar sobre outras janelas.

Uma aplicação usualmente consiste de multiplas atividades que são pouco relacionadas a outras. Tipicamente, uma atividade é uma especificada como a principal (main), que é apresentada ao usuário quando ele chama a aplicação pela primeira vez. Cada atividade pode começar outra atividade para realizar diferentes ações. A cada vez que uma nova atividade se inicia, a atividade anterior é parada, mas o sistema preserva a atividade numa pilha (a chamada "back stack"). Quando uma nova atividade se inicia, ela é colocada na back stack e ganha o foco. O back stack usa o conceito de fila "last in, first out", então quando o usuário terminou a operação e pressiona o botão BACK, a atividade corrente é retirada do topo da pilha (e destruída) e a atividade anterior reinicia.

Quando uma atividade é parada em razão de outra atividade se iniciando, ela é notificada da mudança do seu estado através dos métodos de ciclo de vida da atividade. Existem diversos outros métodos de callback que a atividade pode receber, de acordo com a mudança de seu estado - seja quando o sistema esteja criando a aplicação ou parando-a, reiniciando-a ou a destruindo - e cada callback dá a você a oportunidade de realizar trabalhos específicos que são apropriados para a mudança de estado. Por exemplo, quando parado, a atividade deve liberar objetos de recursos como conexões de rede e bancos de dados. Quando uma atividade se reinicia, você pode capturar os recursos necessários e continuar a ação que foi interrompida. Essas transições de estado são parte do ciclo de vida da atividade.

Criando uma atividade

Para criar uma atividade, você deve criar uma subclasse de Activity (ou de uma subclasse existente). Na sua subclasse, você precisará implementar métodos callback que o sistema chama quando a atividade faz a transição entre os vários estados de seu ciclo de vida, como quando a atividade é criada, parada, reiniciada ou destruída. Os dois métodos callback mais importantes são:

onCreate()
Você deve implementar esse método. O sistema chama esse método quando está criando a atividade. Dentro de sua implementação, você deve inicializar os componentes essenciais para sua atividade. Mais importante ainda, é aqui que você vai chamar setContentView() para definir qual layout será a interface inicial de sua atividade (i.e. aplicação).

onPause()
O sistema chama esse método como a primeira indicação que o usuário está deixando sua atividade (apesar disso não significar que a atividade está sendo destruída). É aqui que você usualmente deverá fazer o commit para quaisquer mudanças que devam ser persistidas.

Existem outros métodos callback dentro do ciclo de vida e que você deverá usar para provêr ao usuário uma experiência fluída entre as atividades e gerenciar interrupções inexperadas que causar a parada ou destruíção de sua atividade. Os métodos de callback foram discutidos em post anterior.

Implementando a interface de usuário

A interface de usuário para uma atividade é provida por uma hierarquia de views - objetos derivados da classe View. Cada view controla um espaço retangular particular dentro da janela onde a atividade está presente e pode responder a interações do usuário. Por exemplo, uma view pode ser um botão que inicia uma ação quando o usuário toca nele.

O Android provê um número de views já prontas que você poderá usar para criar o seu design e organizar o seu layout. Mas isso você já sabe, já que falamos extensivamente de interface. Essas views são os widgets, que provêem elementos visuais e os layouts, que são views derivadas das ViewGroups.

Como sabem também, a forma mais comum de definir layouts é através de arquivos XML salvos como recursos da aplicação.

Declarando a atividade no manifesto

Você deve declarar sua atividade no arquivo de manifesto para que ele possa ser acessível no sistema. Para declarar sua atividade, abra o arquivo de manifesto e adicione um elemento de <activity> como filho do elemento <application>. Por exemplo:

<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >

Existem diversos outros atributos que você pode incluir nesse elemento para definir as propriedades como label para uma atividade, um ícone para uma atividade ou mesmo um tema de estilos para a interface da atividade.

Usando intent filters (filtros de intenção)

Um elemento <activity> pode também especificar vários intent filters - usando o elemento <intent-filter> - para declarar como outros componentes de aplicação devem ser ativados.

Quando você cria uma nova aplicação usando as ferramentas SDK do Android, a atividade básica criada para você automaticamente inclui um intent filter que declara como a atividade deve responder à ação principal (main) e que deveria ser colocada na categoria de launcher. O intent filter se parece como abaixo:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

O elemento <action> especifica que ele é o ponto principal e inicial da aplicação. O elemento <category> especifica que essa atividade deve ser listada na aplicação launcher do sistema (para permitir aos usuários lançar a atividade).

Se você tem a intenção que sua aplicação seja, por assim dizer, privada e que não permita que outras aplicações ativem uma de suas atividades, então você não precisará de nenhum outro intent filter. Apenas uma atividade deve ser a ação principal e estar na categoria launcher, como mostrado no código acima. Atividades que você não quer que sejam disponíveis para outras aplicações não devem ter nenhum intent filter e você pode inicia-las você mesmo usando explicit intents (que serão discutidos em breve).

Contudo, se você quer que sua atividade responda a implicit intents que são entregues a partir de outras aplicações (e suas próprias), então você deve definir intent filters adicionais para sua atividade. Praa cada tipo de intent ao qual você quer responder, você deve incluir o elemento <intent-filter> que inclui um elemento <action> e, opcionalmente, um elemento <category> e/ou elemento <data>. Esses elementos especificam o tipo de intent ao qual você quer que sua atividade possa responder.

Falaremos sobre intents em breve, num post só para ele.

Iniciando uma atividade

Você pode começar uma outra atividade chamando startActivity(), passando para ele um Intent que descreve a atividade que você quer iniciar. O intent especifica ou a atividade exata que você quer iniciar ou descreve o tipo de ação que você quer executar (e o sistema seleciona a atividade apropriada para você, que pode inclusive ser uma aplicação diferente). Um intent pode também trazer consigo pequenas quantidades de dados a serem usados pela atividade que está sendo iniciada.

Quando trabalhando na sua própria aplicação, você também vai normalmente precisar lançar uma atividade conhecida. Você pode fazê-lo criando um intent que explicitamente define a aplicação que você quer iniciar, usando o nome de classe. Por exemplo, aqui está como uma atividade inicia outra atividade chamada SignInActivity:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

Contudo, sua aplicação deve também querer executar alguma ação como enviar um email, mensagem de texto ou fazer o update no status ou mesmo usar dados de sua atividade. Nesse caso, sua aplicação pode não ter, dentro de suas atividades, uma que realize a ação esperada. Então, ao invés de criar uma atividade apenas para aquela ação, você poderá usar outras atividades providas por outras aplicações dentro do seu dispositivo. É aqui que os intents são realmente valiosos - você pode criar um intent que descreve uma ação que você quer realizar e o sistema lança a atividade apropriada a partir de outra aplicação.

Se existem multiplas atividades que podem realizar o intent, então o usuário poderá selecionar qual quer usar. É como quando você instala um app que realiza a tarefa de mostrar uma galeria de imagens. Caso você tenha dois ou mais apps que fazem a mesma função, ao tentar abrir uma imagem a partir de um app que não tenha essa funcionalidade, o Android perguntará na tela com qual app ele deverá realizar a tarefa. No exemplo abaixo, se você quer permitir que o usuário envie uma mensagem de email, você pode criar o intent seguinte:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
O EXTRA_EMAIL extra adicionado no intent é uma array de string de endereços de email aos quais o email pode ser enviado. Quando uma aplicação de email responde a esse intent, ele lê a array de string provida e coloca no campo "para" do formulário de composição do email. Nessa situação, a aplicação de email inicia e quando o usuário tiver terminado de enviar o email, a atividade anterior reinicia.

Iniciando uma atividade para um resultado

Algumas vezes, você pode querer receber um resultado a partir de uma atividade que você iniciou. Nesse caso, inicie a atividade chamando startActivityForResult() (ao invés de startActivity()). Para então receber o resultado de uma atividade subsequente, implemente o método callback onActivityResult(). Quando a atividade subsequente estiver finalizada, ele retorna um resultado para um Intent dentro do seu onActivityResult().

Por exemplo, talvez você queira que o usuário selecione um dos seus contatos para que a atividade possa fazer alguma coisa com a informação que está em seu contato. Aqui abaixo está como você pode criar tal intent e como manusear o resultado:

private void pickContact() {
    // Cria um intent para "pegar" um contato como definido pelo content provider URI
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Se a requisição foi bem sucedida (OK) e a requisição foi PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Faz um query no content provider dos contatos para recuperar o nome do contato
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // Verdadeiro se o cursor não for vazio
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Faz algo com o nome do contato selecionado...
        }
    }
}
Esse exemplo mostra a lógica básica que você deverá usar em seu método onActivityResult() para que possamos manusear corretamente o resultado da atividade. A primeira condição checa se a requisição foi bem sucedida - e se foi, então o resultCode retornará RESULT_OK - e se a requisição para a qual o resultado está sendo retornado é conhecido - nesse caso, o requestCode bate com o segundo parâmetro enviado para startActivityForResult(). A partir dai, o código manuseia o resultado da atividade fazendo a leitura do dado retornado em um intent (a partir do parâmetro data).

O que acontece é que o ContentResolver realiza uma query no content provider que retorna um Cursor que permite que os dados retornados possam ser lidos. Mas vamos falar de content provider com mais propriedade também em um post só para ele.

Encerrando uma atividade

Você pode encerrar uma atividade chamando o método finish(). Você também pode encerrar uma atividade separada que você iniciou anteriormente chamando finishActivity().

Nota: Em muitos casos, você não deve explicitamente finalizar uma atividade usando esses métodos. O ideal é deixar o sistema Android gerenciar a vida da atividade para você. Chamar esses métodos podem afetar negativamente a experiência do usuário e deverá apenas ser usando quando absolutamente necessário.

0 comentários:

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Related Posts Plugin for WordPress, Blogger...