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.

sexta-feira, 22 de abril de 2011

Hello, Android!

Eu prometi que iniciaria os exemplos a partir da tela de recursos técnicos do Android (mais precisamente com os projetos de Note Pad e Contact Manager). Mas depois, vendo direito o site, vi que existem exemplos de tutoriais.

Então, achei melhor começar por eles. Assim a gente vai ter contato com exemplos desde os mais simples aos mais avançados, ok? De qualquer forma, o Note Pad e Contact Manager serão mostrados aqui no blog.

O exemplo que vou pegar, o "Hello, World", pode ser encontrado nesse endereço. De qualquer forma, comentarei o exemplo na integra aqui. Esse post será em partes parecido com um que escrevi logo no início deste blog, chamado Criando um novo projeto Android. No entanto, com o conhecimento que adquirimos desde que escrevi o post citado, será MUITO mais fácil entender o código.

Vamos começar do início. Como desenvolvedor, normalmente começamos com o exemplo clássico do Hello, World. O que precisaremos para fazer esse exemplo rodar? Abaixo vão os passos:

  1. Instalar a plataforma (Passos 01, 02, 03 e 04)
  2. Criar um AVD - Android Virtual Device.
  3. Criar o projeto Android dentro do Eclipse.

No caso do passo 2, você poderá usar o seu smartphone para rodar o app assim que você clicar em debug. Ao invés de abrir o emulador, o Eclipse envia o app direto para o smartphone e você pode rodá-lo por lá. A vantagem é que não é preciso usar recursos do seu PC para tal tarefa. Isso será especialmente válido para apps para tablets, uma vez que a emulação do Honeycomb é bastante pesada. O caro, obviamente, é comprar um tablet. Caso queira saber como rodar o app direto no smartphone, entre nesse link que explica como debuggar.

Depois de criar seu novo projeto Android e rodá-lo (seja no emulador ou no smartphone), vamos ver o que foi criado de código.

Abra o arquivo HelloAndroid.java. O código deverá ser como o mostrado abaixo:


package com.example.helloandroid;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
    /* Chamado quando a atividade é criada pela primeira vez */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

O que esse código nos mostra?

A primeira linha mostra o pacote no qual a classe está inserida. Isso quer dizer que se alguém quiser acessar a classe HelloAndroid ela terá de colocar o caminho com.example.helloAndroid.HelloAndroid. Ou então, fazer um import do pacote.

As linhas seguintes mostram os imports da classe. Isso quer dizer que são esses pacotes que serão usados nessa classe. Quando você coloca em código o import, faz com que não seja preciso, no código da classe, fazer o referenciamento completo para a classe. Se não tivessemos importado a class android.app.Activity, a classe HelloAndroid deveria ser extendida a partir de android.app.Activity e não somente Activity como mostrado acima.

Os dois pacotes importados foram android.app.Activityandroid.os.Bundle.

Após isso, a classe HelloAndroid é efetivamente criada. Ela será extendida a partir da classe Activity. Isso faz dela uma classe que herda as propriedades da classe Activity e, portanto, faz com que ela tenha propriedades especiais que o sistema Android interpretará para rodá-la.

E, por fim, um único método é criado, chamado onCreate. Esse método é chamado no momento que a atividade é criada e é este recebe um Bundle com os dados da instância, caso estejamos reabrindo a aplicação após ter sido pausada (ver Ciclo de vida de uma aplicação Android). Caso seja a primeira vez que a aplicação está sendo rodada, recebe null como parâmetro.

Uma vez que a funcionalidade padrão do método onCreate não será alterada, a primeira linha do método faz a chamada de super.onCreate(savedInstanceState). Quando chamamos super.onCreate, estamos chamando o método onCreate da classe pai (nesse caso, da classe Activity). Isso faz com que o onCreate padrão seja chamado a partir do código de implementação da classe Activity. Ponto para programação orientada a objetos. Nossa classe tem as funcionalidades de uma atividade mas não precisamos reescrever código. Basta fazer uma chamada para o método cujas funcionalidades já foram escritas e que estão presentes na classe Activity para que elas sejam rodadas a partir da classe HelloWorld.

A linha seguinte, setContentView(R.layout.main) está especificando que o arquivo de recurso que deverá se mostrado quando a aplicação for chamada é o de nome main.xml. Caso fosse necessário fazer com que outro recurso de layout fosse a primeiro a ser carregada quando a aplicação fosse executado, bastaria mudar a chamada dentro de setContentView.

E o que, afinal de contas, é esse R maiúsculo que vemos no código?

O R é uma referência aos Resources (ou recursos) da sua aplicação. É um arquivo que indexa todos os recursos definidos no seu projeto. Você usa essa classe em seu código fonte como um atalho para se referir a recursos que você incluiu no projeto. É particularmente poderoso com as capacidades de code-completion de IDEs como Eclipse já que permite que você rapidamente e interativamente localize a referência especifica que está procurando.

Abrindo o arquivo R.java que se encontra na pasta gen/ você verá todos os recursos da sua aplicação lá descritos. Perceba uma classe interna chamada "layout" e um campo membro chamado "main". O plugin ADT no Eclipse é quem criou essa seção. Ele "percebeu" a existência do arquivo main.xml e gerou uma classe para ele. Se você adicionar outros recursos ao seu projeto (como strings dentro de res/values/strings.xml ou imagens dentro de res/drawable) o seu arquivo R.java será mudado para refletir essas mudanças.

/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found.  It
 * should not be modified by hand.
 */
package com.example.helloandroid;
public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int icon=0x7f020000;
    }
    public static final class id {
        public static final int textview=0x7f050000;
    }
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class string {
        public static final int app_name=0x7f040001;
        public static final int hello=0x7f040000;
    }
}


Se você não estiver usando o Eclipse, essa classe será gerada para você quando você estiver compilando o projeto.

Nota: Você nunca deverá editar esse arquivo manualmente. Deixe que o Eclipse, através do plugin ADT, faça as modificações para você.

Se por um lado os recursos devem estar relacionados no arquivo R.java, as atividades devem todas estar descritas no arquivo de manifesto:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.helloandroid"
      android:versionCode="1"
      android:versionName="1.0">
 
    <uses-sdk android:minSdkVersion="7" /> 
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".HelloAndroid"
                  android:label="@string/app_name">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

Eu fiz a separação em cores para poder explicar melhor o arquivo. Na parte cinza, lá em cima, existe a declaração do arquivo XML. Essa declaração é padrão da XML e não deverá ser modificada.

Na segunda parte, em vermelho, temos o início da chave manifest, que traz alguns dados importantes a respeito da aplicação. Vejam que existe alguns atributos, sendo eles:

  • package - Mostra qual é o pacote da aplicação. Isso é que mostrará para o sistema Android qual é a identificação da aplicação.
  • android:versionCode - Mostra a versão do código. Atualmente, na versão 1.
  • android:versionName - Mostra a versão do código em formato mais, digamos, didático ao usuário. Atualmente na versão 1.0.

Em azul, vemos a seção <uses-sdk> que tem apenas um atributo: android:minSdkVersion indicando o número 7. Isso diz respeito à versão da API que será a versão mínima na qual o app vai conseguir rodar. Nesse caso, a API 7 representa a versão do Android SDK 2.1 update 1. A tabela de SDK e valores de API você encontra aqui.

Em verde temos a abertura da seção de <application>, que trará as configurações a respeito da aplicação em si.

Em roxo, temos a seção <activity>, que descreve a única atividade existente na aplicação. No caso, a atividade existente é a HelloAndroid. 

E por fim, em laranja, temos a seção <intent-filter>. Nela temos algumas entradas que descrevem a ação e a categoria da atividade. O intent-filter é responsável por comunicar ao sistema Android a intenção (intent, em inglês) da aplicação e de uma determinada atividade interna a ela. É uma palavra que pode confundir já que dá a entender que, por ter uma intenção, deverá ser executada com tal finalidade. Na verdade, ela tem uma intenção em si mas só será executada se e quando solicitada. 

Explico: veja que existe a tag action dentro de intent-filter. O atributo interno a essa tag é o android:name e que está marcado como android.intent.action.MAIN. Além dela, existe a tag category que tem como android:name a inscrição android.intent.category.LAUNCHER.

A primeira linha diz que essa atividade será a principal e que, além de inflar o recurso de layout main.xml na tela, deverá rodar essa atividade inicialmente.

Já a segunda linha, a de category, especifica que a aplicação deverá ser mostrada no launcher do Android e que, portanto, poderá ser acessada bastando tocar no ícone dele na tela do smartphone.

Quando a aplicação roda, a tela ao lado é mostrada:

O que aconteceu? A aplicação subiu e inflou o recurso de layout e executou a atividade que estava marcada como MAIN diretamente na tela.

E se quisessemos não chamar a view padrão e definir algum conteúdo a ser inflado na tela inicialmente de maneira programática?

Bastaria, para tal, modificar a classe para o código que você vê abaixo:


package com.example.helloandroid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
   /** Chamado quando a atividade é criada pela primeira vez */
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       TextView tv = new TextView(this);
       tv.setText("Esse é um TextView carregado direto na tela a partir do método OnCreate");
       setContentView(tv);

   }
}
O que mudou no código acima do anterior? Fizemos um novo import de android.widget.TextView e dentro do método onCreate, dimensionamos uma variável do tipo TextView, inserimos um valor dentro dele e colocamos essa TextView como sendo o conteúdo a ser mostrado.

O resultado é o seguinte:


Obviamente, como vimos no post que fala sobre Declaração de Layouts, não vale a pena inserir um TextView diretamente na tela. Afinal, o que faremos apenas com esse widget na tela? Absolutamente nada. O ideal é inserir um TextView dentro de algum tipo de layout já que declarar o layout programaticamente é possível, como visto, mas faz da manutenção do código um inferno rapidamente.

E como fazer a declaração deste TextView diretamente em um arquivo de layout e fazer com que o aplicativo o chamasse e eu não precisasse fazer a declaração via código do meu layout? É simples e é que vamos fazer abaixo.

Dentro do Eclipse, expanda a árvore de diretórios até achar a /res/layout/. Dentro dele haverá um arquivo chamado main.xml (nome sugestivo, não? principal.xml na tradução para o português).


Substitua o conteúdo do arquivo pelo conteúdo abaixo:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/textview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:text="@string/hello"/>
Dentro da pasta /res/values/ abra o arquivo strings.xml. Aqui é onde você deverá guardar todos os textos padrões da sua interface de usuário. E qual a razão para se fazer isso? Imagine que você queira fazer um aplicativo que seja voltado para o público que fala português. Dai você cria o aplicativo e vai inserindo os textos que deverão aparecer nos widgets diretamente no corpo do XML responsável pelo layout. Ou seja, no lugar de @string/hello, como aparece acima, você coloca diretamente o texto que deseja que apareça. O problema dessa abordagem é que se um dia você quiser fazer com que seu aplicativo possa ser usado por um público que fala inglês, francês ou qualquer outra lingua, você terá de percorrer todos os arquivos de layout fazendo a modificação diretamente no XML ao passo que usando um arquivo como o strings.xml você mantem todas as mensagens em um local apenas.

Uma vez aberto o arquivo strings.xml, você verá o seguinte conteúdo:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, HelloAndroid!</string>
    <string name="app_name">Hello, Android</string>
</resources>
Modifique a string hello para a mensagem que deseja. Eu mudarei para "Olá mundo, eu fui preenchido com uma string de recurso!". Veja que quando o código android:text é setado para @string/hello, o que o aplicativo fará é substituir essa entrada pela mensagem correspondente existente em strings.xml.

Por fim, faça com que o código da classe HelloAndroid.java fique como era inicialmente:

package com.example.helloandroid;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
    /* Chamado quando a atividade é criada pela primeira vez */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Ao rodar a aplicação, você terá o seguinte resultado:


E esse foi o primeiro exemplo de código comentado aqui no blog CeleiroAndroid. Nos próximos posts, mais código e mais entendimento de como as peças são encaixadas para se criar um "motor" de aplicativo Android. Até mais!

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...