Estrutura do Android

<< Click to Display Table of Contents >>

Navigation:  Android Studio >

Estrutura do Android

Previous pageReturn to chapter overviewNext page

Visualização do ambiente

Atualizações

Estrutura de um projeto Android

Como pesquisar algo no Google

Controle de versão

Dicas

Erros


Vamo a algumas configurações do Android Studio e algumas informações sobre programação Android.

 

Visualização do ambiente

Após criar o projeto, se você não estiver vendo a janela acima vá no menu "View -> Tool Windows -> Project", esta janela mostra a estrutura do seu projeto. A forma de exibição para voce deve estar diferente da imagem acima neste momento, isto porque o Android Studio possui algumas formas diferentes de mostrar o mesmo projeto, para alternar entres essas formas clique no local indicado em vermelho na imagem acima. Na maior parte do tempo é utilizado o padrão "Android", que oculta arquivos não importantes e mostra numa estrutura de melhor manuseio, para visualizar extamente a estrutura que esta salva no disco você pode modificar para o padrão "Project".

 

Atualizações

Para verificar atualizações do Android Studio vá no menu "Help -> Check for Update".

Para verificar atualizações no SDK do Android vá no menu "Tools -> Android -> SDK Manager" (Existe um atalho na barra de ferramentas como mesmo icone do menu).

 

Estrutura de um projeto Android

AndroidManifest.xml

O arquivo "AndroidManifest.xml" é quem possui informações sobre o aplicativo, ele indica o nome para o usuário, nome único de identificação para o Google Play (package), versão do aplicativo, menor versão de Android suportada, versão do SDK para compilar o projeto, telas que existem no aplicativo, filtro de ações globais (Você pode abrir seu aplicativo ao receber um SMS, entre diversas outras possibilidades), permissões que seu aplicativo deve possuir (Leitura de contatos, gravação no armazenamento externas, entre várias outras).

Ao trabalhar com o Android Studio algumas das informações ditas acima não estarão presentes no AndroidManifest.xml, isto porque o gradle regera este arquivo ao compilar e mescla informações contidas no arquivo build.gradle do projeto a ele (Se não sabe do que estou falando lei o tutorial anterior primeiro Entendendo a ferramenta).

Vamos ver nosso arquivo gradle:

android {

    compileSdkVersion 10

    buildToolsVersion "20.0.0"

 

    defaultConfig {

        applicationId "br.com.market.vendas"

        minSdkVersion 10

        targetSdkVersion 10

        versionCode 53

        versionName "1.4.1"

    }

}

Este trecho do arquivo é referente a informações que serão mecladas dentro do AndroidManifest.xml, a entrada "applicationId" será convertida para a tag "package" no Manifest, com as demais informações ocorre o mesmo.

 

Voltando ao arquivo AndroidManifest.xml, todas as telas do sistema devem estar registradas aqui dentro para poder ser utilizada, se não vai dar um erro inexplicavel.

Também informamos a tela que deve ser aberta ao iniciar o sistema, definimos o título da tela, podemos configurar a tela para não girar com o aplicativo ou para que quando girada não seja reinstanciada, entre diversas outras configurações.

 

Context

Você verá esta classe infinitamente no Android, tudo o que você for fazer que meche com visual ou com recursos do sistema (Arquivos, banco de dados, GPS, etc) será solicitado o contexto. Isto é a própria tela em execução no atual momento (this).

Exemplo: Ao exibir uma mensagem de confirmação para o usuário é necessário informar o contexto (this) que receberá esta mensagem.

Quando é chamada uma nova tela também é feito informando o contexto atual, mas atenção, não invente de fazer uma variável estatica atribuindo o contexto da tela inicial do sistema só pra não enviar esta informação por parâmetro ao seus métodos, vai dar problema. Quando uma tela é chamada sobre outra a execução da primeira tela é parada e vai dar problema se você insistir em fazer isso, vai começar a fechar do nada sua aplicação sem você saber o erro. Pesquise sobre "ciclo de vida da Activity Android" para maiores detalhes.

Quando você utiliza GPS é necessário informar o contexto que irá utilizar, porém se você girar o celular tudo é recriado no Android (Veremos no próximo tópico isso) e assim o processo do GPS será reiniciado, causando incomodo pois não é instântâneo obter informações dele. Para resolver isto você pode utilizar "getApplicationContext()" no lugar do "this" ao iniciar o GPS. Agora não haverá mais o problema, mas não se esqueça de finalizar a utilização do GPS em algum ponto, pois ficará ativo durante toda utilização do aplicativo, raramete é utilizo isso.

 

Activity (Telas)

Uma tela em Android é chamada de Activity, você deve criar uma classe que descenda de Activity e "inflar" um layout XML criado nos recursos (Ou definir tudo manualmente).

Porém se você estiver desenvolvendo um projeto que funcione desde as versão 2.x até as mais recentes você não poderá utilizar alguns recursos da Activity, como ActionBar, Fragmentos, entre outros. Para utilizar tais recursos você deve utilizar as bibliotecas de suporte desenvolvidas pelo google, estas estão disponíveis no "SDK Manager", com elas você passará a descender sua Activity da classe "android.support.v4.app.ActionBarActivity". Esta é uma cópia da Activity padrão e com os novos recursos disponíveis a partir de versões mais recentes do Android.

Quando você gira a tela de seu aparelho os componentes não são apenas readaptados a nova dimensão, toda a tela e recriada, portanto pode ser necessário salvar valores e restaura-los manualmente após a recriação. Pesquise sobre "ciclo de vida da Activity Android" para maiores detalhes. Este comportamento pode ser desabilitado (giro da tela ou a recriação da Activity quando girada), mas não recomendo fazer isso, pois é coisa de vádio e tem impacto no processamento dos recursos a desabilitação da recriação de Activity. A desabilitação destas configurações é pelo AndroidManifest.xml na tag referente a activity.

Desabilitar giro de tela: android:screenOrientation="portrait".

Desabilitar recriação da activity ao giriar: android:configChanges="orientation"

Desabilitar abertura automatica do teclado ao abrir a tela: android:configChanges="keyboardHidden"

Mesclando configurações: android:configChanges="keyboardHidden | orientation | screenSize"

 

Uma diferença chata que você terá que se adaptar, é que quando é criado uma "Activity" não é possível mandar a intância de um objeto via referência de uma tela para outra, não é possível criar um construtor que receba esta instância (ou qualquer outro valor) e armazena-la numa variável interna e ir manipulando a mesma instância do objeto em Activity's diferentes (Até daria, mas ao girar a tela você vai se encomodar e o outro problema será criado).

A Activity é instanciada a partir de uma "Intent", e nesta Intent é definido os parâmetros a serem enviados para Activity, porém se você for passar um objeto o mesmo será serializado neste momento, e a Activity que foi chamada irá deserializa-lo, assim trabalhando com uma nova instância.

Intent intent = new Intent(mContext, ProdutoActivity.class);

intent.putExtra(CHAVEVALOR);

this.startActivity(intent); // Onde "this" é um Context / Activity

 

 

Outra diferença é que não é possivel chamar a activity em "showModal" travando a execução do fonte e após fecha-la continuar no ponto que estava antes, isso é feito similar a processamentos assincronos, ao iniciar a nova Activity será informado uma identificação qualquer, e quando ela terminar sua execução e retornar a activity anterior você receberá esta identificação pelo método "onActivityResult" e assim continuará seu processamento.

Intent intent = new Intent(mContext, ProdutoActivity.class);

intent.putExtra(CHAVE, VALOR);

this.startActivityForResult(intent, CODIGO_INTEIRO_NOVO_CADASTRO);

 

// Agora na sua activity é necessário tratar este retorno, para isto faremos como indicado abaixo.

// No tratamento deste retorno recebemos 3 parâmetros:

// * requestCode => Código enviado anteriormente para a atividade

// * resultCode => Você pode ou não trabalhar com esta informação, você pode definir qualquer valor dentro da Activity chamada, 

//                                geralmente utilizo para indicar que pressionei no "Gravar" da outra activity, pois independente do que for feito na outra acitivty

//                                no momento que ela for finalizada e voltar para esta será executado este método

// * data => Você pode definir várias informações para retornar para esta activity a partir da que foi chamada

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

 switch (requestCode) {

         case CODIGO_INTEIRO_NOVO_CADASTRO: 

                 if (resultCode == Activity.RESULT_OK) {

                         Toast.makeText(this, "Registro cadastrado: " + data.getIntExtra(CHAVE, 0), Toast.LENGTH_LONG).show();

                         atualizarLista();

                 }

                 break;

 }

}

 

// Agora o exemplo de como enviar o retorno a partir da acitivty que foi chamada para executar os passos acima

private void botaoSalvarClick(View view) {

 Intent ret = new Intent();

   ret.putExtra(CHAVE, VALOR);

   setResult(Activity.RESULT_OK, ret);

   finish();

}

 

 

 

 

Para dar uma mensagem na tela e depois da ação do usuário executar algo também não existe o "showModal", mas nessa situação não é necessário fazer da forma acima. Nesta situação é utilizado o "AlertDialog" isto cria algo sobre a sua activity mas não interrompe o clico de vida dela, e você pode informar o procedimento a ser executado quando clicado no botão, Fiz a classe "br.com.market.lib.Msg" para auxiliar nisto.

 

Msg.confirmDialog(  this,

                    "Confirma excluir registro com sucesso desejando?",

                    new OnClickListener() { // Cuidado com esta interface pois existem duas para tipos diferentes, aqui é utilizada a android.content.DialogInterface.OnClickListener

                                @Override

                                public void onClick(DialogInterface dialogInterface, int i) {

                                    // Clicou no botão OK

                                }

                    },

                    new OnClickListener() {

                                @Override

                                public void onClick(DialogInterface dialogInterface, int i) {

                                    // Clicou no botão cancelar

                                }

                    });

 

 

Arquivo de recursos

Os recursos do projeto ficam na pasta ".\PROJETO\src\main\res", este são as imagens, telas, textos, menus. Dentro desta pasta cada tipo de recurso estará localizado numa subpasta:

anim: Arquivos para configurar animações, são elas: transações entre telas e fragmentos, deslocamento de controle visual na tela, entre outros.

drawable: Imagens a serem utilizadas

layout: Telas do sistema.

menu: Menus do sistema.

values: Aqui podem ser configurados textos para serem utilizados na telas (O padrão diz pra utilizar sempre os recursos para textos de exibição ao usuário, nunca crava-los no código fonte como string, pois depois para tradução basta traduzir o XML, que é muito mais facil e tem melhor controle). Ainda dentro do values é possivel definir valores inteiro, booleanos, dimensões (tamanho em pixel, dpi, sp para fontes). Existem também os "styles" que definem o tema do projeto, é possivel definir valores globais como as cores padrões, animações, tamanhos e muito mais.

 

O grande problema da programação Android (Além da bosta do Java) é a diversidade de aparelhos, com as mais variadas versões do sistema operacional, tamanho de tela, e densidade, e a melhor opção é manter um projeto pra tudo do que manter vários em paralelo. Em relação ao tamanho de tela o Google fez algo bom, que é não deixar você de preocupar em verificações no estilo "if (largura_da_tela > X pixel) tamanho_fonte = Y", as telas são classificadas respectivamente em: ldpi, mdpi, hdpi, xhdpi e xxhdpi, você apenas trata este tipo de informaçõe que o sistema operacional te informa (Para maiores detalhes dos tamanho pesquise no Google).

E para isto os recursos possuem uma grande utilidade, estes valores fixos configurados nos XML são variáveis de acordo com as caracteristicas do aparelho. é possivel definir recursos diferentes para cada caracteristica.

Exemplo: A fonte padrão no meu sistema é 12sp, se o celular do usuário for de alta resolução será 16sp e ser for um tablet será 20sp. Para resolver esta situação basta definir os 3 passos abaixo

.\res\values\arquivo.xml: Definir tag <dimen name="tamanho_texto">12sp</dimen>.

.\res\values-hdpi\arquivo.xml: Definir tag <dimen name="tamanho_texto">16sp</dimen>.

.\res\values-large\arquivo.xml: Definir tag <dimen name="tamanho_texto">20sp</dimen>.

Pronto, agora no seu XML de layout onde haver o controle visual deste texto basta definir o tamanho da fonte com este recurso (android:textSize="@dimen/tamanho_texto").

Existem vários tipos de palavras chaves para utilizar em cada subpasta de recursos, sendo que quando não é localizado dentro da pasta especifica será utilizado o padrão, exemplos:

.\res\RECURSO-v11: Se a versão do Android que estiver executando o programa for 11 (3.0 olhe no SDK Manager para saber esta relação) ou superior será utilizado esta pasta de recursos.

.\res\RECURSO-land: Se estiver em land scape.

.\res\RECURSO-large-portrait: Se for um tablet e estiver no modo retrato

.\res\RECURSO-sw600dp: Se a largura for maior ou igual a 600dp (Não sei se é qualquer valor de largura que é permitido aqui)

.\res\RECURSO-hdpi: Se a tela do aparelho for de alta resolução.

 

Listas

Controles que trabalham com listas como ListView, Spinner (ComboBox), ExpandableListView funcionam lendo seus itens de uma classe implementanda de "Adapter" e exibindo-os na tela. Para cada tipo de situação pode existir um adapter diferente, você quase sempre implementará seu adapter por conta destas particularidades (Descendo de Adapter ou algo superior, pesquise no Google para mais informações).

O adapter trabalha recebendo a lista de objetos que será exibida, como List<?> ou array, e você irá sobrescrever o método "public View getView(int position, View convertView, ViewGroup parent)" para retornar o layout para o item da lista como quiser. O parâmetro "convertView" é o segredo para melhor desempenho em listas, o Android trabalha instanciando a view's somente dos itens que estão sendo exibidos na tela, ao rolar a lista fazendo a solicitação da view de um outro item da lista, o Android informa ao método getView() a instância da view que desapareceu através deste parâmetro, assim você notará melhor desempenho readaptando a instância já existente do que criando uma nova intância para cada solicitação de view, para isto você geralmente trabalhará como o indicado abaixo:

public View getView(int position, View convertView, ViewGroup parent)

 if (convertView == null) {

         convertView = LayoutInflater.from(getContext).inflate(R.layout.ID_lAYOUT, null);

 }

 ((TextView)converView.findViewById(R.id.ID_TEXTO)).setText("Exemplo");

 // Resjute suas personalizações, tome cuidade com a visibilidade de controles se você esconde controles aqui,

 // por estar reutilizando uma instância de outro item você deve deixar explicito se é pra mostrar ou não ao invés de simplemente fazer um if mandando esconde-lo.

}

 

Depois de implementado o adapter você deve vincular ele a sua lista, isto é no código fonte da sua atividade:

MeuAdapter adapter = new MeuAdapter(minhaListaDeObjeto); // Este construtor você criou no seu adapter sobreescrevendo os originais que recebem mais parâmetros que são uteis apenas em listas simples, você pode mandar null e 0 ao realizar o super() no novo construtor

((ListView)findViewById(R.id.MINHA_LISTA)).setAdapter(adapter);

 

 

O controle Spinner (ComboBox) deve receber um SpinnerAdapter, a diferença deste adaptador é que ele possui o método "getDropDownView()", com este método é possivel mostrar uma view diferente quando o spinner estiver fechado apenas mostrando o item selecionado na Activity, ao clicar nele é aberto o popup que recebe as view's do método "getView()" da mesma forma como um lista do exemplo anterior, não é necessário implementa-lo.

O controle ExpandableListView recebe um ExpandableListAdapter, onde é possivel definir uma view para o grupo e outra para os itens.

 

Como pesquisar algo no Google

As vezes você quer procurar algo que você sabe como fazer com recursos no arquivo de layout mais não sabe via fonte Java, uma dica é procurar utilizando a palavara "programmatically", por exemplo:

Pesquise "android set text size" no Google, você localizará várias dicas de como fazer isso utilizando os arquivos XML, que não era o objetivo da sua pesquisa.

Agora pesquise "android set text size programmatically", você localizará o código fonte Java para fazer isso em tempo de execução.

 

 

Controle de versão

Na hora de adicionar seus fontes ao controle de versão você pode adicionar toda a pasta sem se preocupar com o que é necessário se você for cabaço, mas você deve adicionar somente os arquivos que não são referentes ao computador local e nem os arquivos que são regerados pelo Android Studio ao compilar. Portando partindo do diretório raiz do seu projeto onde existe o "settings.gradle" vamos adicionar esses arquivos e diretórios a lista de arquivos ignorados do controle de versão:

Tipo

Nome

Pasta

.gradle

Arquivo

.idea\workspace.xml

Pasta

.idea\libraries

Pasta

build

Arquivo

local.properties

Arquivos

*.iml

Arquivo

PROJETO\*.iml

Pasta

PROJETO\build

 

 

Dicas

Datas

Trabalhar com data no Java é terrivel, para melhorar isto existe o framework "joda-time" que possui muitos métodos melhores, utilize a classe DateTime deste framework para trabalhar.

 

Erros

Erro "Copy Array [ C [" (Não tenho mais a mensagem exata)

Ocorre no "Preview" do layout (visualizador do Android Studio) e para resolver basta mudar a versão do SDK que o preview esta utilizando, clique no icone do Android onde esta apontando a versão do SDK e altere para versão 19.