Você está na página 1de 267

A

n
d
e
r
s
o
n

D
u
a
r
t
e

d
e

A
m
o
r
i
m

2
0
1
1

A
N
D
R
O
I
D
,

u
m
a

v
i
s

o

g
e
r
a
l

ANDROID, uma viso geral Anderson Duarte de Amorim
2
Contedo
Introduo ....................................................................................................................... 10
Atividades ....................................................................................................................... 11
Criar uma atividade .................................................................................................... 11
Implementando uma interface de usurio ................................................................... 12
Declarando a atividade no manifesto.......................................................................... 13
O uso de filtros inteno ............................................................................................. 13
Iniciar uma atividade .................................................................................................. 14
Iniciar uma atividade para um resultado..................................................................... 15
Encerrar uma atividade ............................................................................................... 16
Gerenciando o ciclo de atividade................................................................................ 16
Aplicar o ciclo de vida callbacks ................................................................................ 17
Salvando estado de atividade ...................................................................................... 23
Manipulao de alteraes na configurao ............................................................... 25
Coordenar as atividades .............................................................................................. 26
Fragmentos ..................................................................................................................... 27
Filosofia de design ...................................................................................................... 27
Criando um fragmento ................................................................................................ 29
DialogFragment ...................................................................................................... 30
ListFragment ........................................................................................................... 31
PreferenceFragment ................................................................................................ 31
Adicionando uma interface de usurio ................................................................... 31
Criando um layout .................................................................................................. 32
Adicionando um fragmento de uma atividade ........................................................ 32
Adicionando um fragmento sem uma interface de usurio (UI) ............................ 34
Gerenciando fragmentos ......................................................................................... 35
Executando transaes com fragmento .................................................................. 35
ANDROID, uma viso geral Anderson Duarte de Amorim
3
Comunicando-se com a atividade ........................................................................... 37
Criar callbacks evento para a atividade .................................................................. 38
Adicionando itens barra de ao .......................................................................... 39
Manuseio do ciclo de vida do fragmento................................................................ 40
Coordenao com o ciclo de vida de atividade ...................................................... 41
Loaders ........................................................................................................................... 43
Resumo API Loader ................................................................................................... 43
Usando carregadores em um aplicativo ...................................................................... 44
Iniciando um Loader ............................................................................................... 45
Reiniciando o Loader.............................................................................................. 46
Usando callbacks do LoaderManager..................................................................... 47
Exemplo ...................................................................................................................... 50
Tarefas e pilha de execuo ............................................................................................ 53
Salvando estado de atividade ...................................................................................... 56
Gerenciando tarefas .................................................................................................... 57
Definio de modos de lanamento ............................................................................ 58
Usando o arquivo de manifesto .................................................................................. 59
Usando as opes de intenes ................................................................................... 61
Manipulao de afinidades ......................................................................................... 62
Limpando a pilha de volta .......................................................................................... 64
Iniciando uma tarefa ................................................................................................... 65
Servios .......................................................................................................................... 66
O bsico ...................................................................................................................... 67
Voc deve utilizar um servio ou um thread? ........................................................ 67
Declarando um servio no manifesto ..................................................................... 69
Criando um servio iniciado ....................................................................................... 70
Segmentao Android 1.6 ou inferior..................................................................... 70
ANDROID, uma viso geral Anderson Duarte de Amorim
4
Estendendo a classe IntentService .......................................................................... 71
Estendendo a classe de servio ............................................................................... 73
Iniciando um servio .............................................................................................. 77
Parando um servio ................................................................................................ 77
Criando um servio vinculado .................................................................................... 78
Enviando notificaes para o usurio ......................................................................... 79
Executando um servio em primeiro plano ................................................................ 79
Gerenciando ciclo de vida de um servio ................................................................... 80
Aplicando o ciclo de vida dos callbacks ................................................................. 81
Servios vinculados ........................................................................................................ 84
O bsico ...................................................................................................................... 84
Vinculao a um servio iniciado ........................................................................... 84
Criando um servio ligado .......................................................................................... 85
Estendendo a classe Binder .................................................................................... 87
Usando um Messenger ........................................................................................... 90
Vinculao a um servio............................................................................................. 93
Notas adicionais ...................................................................................................... 95
Gerenciando o ciclo de vida de um servio de associao ......................................... 96
Processos e threads ......................................................................................................... 98
Processos .................................................................................................................... 98
Ciclo de vida do processo ....................................................................................... 99
Thread ....................................................................................................................... 102
Threads funcionais ................................................................................................ 103
Usando AsyncTask ............................................................................................... 104
Mtodos de Thread-safe ....................................................................................... 106
Comunicao entre processos ................................................................................... 106
Interface de usurio ...................................................................................................... 108
ANDROID, uma viso geral Anderson Duarte de Amorim
5
Hierarquia de view.................................................................................................... 108
Como o Android desenha views ........................................................................... 109
Layout ....................................................................................................................... 111
Widgets ..................................................................................................................... 112
Eventos UI ................................................................................................................ 114
Menus ....................................................................................................................... 114
Tpicos Avanados .................................................................................................. 115
Adaptadores .......................................................................................................... 115
Estilos e Temas ..................................................................................................... 116
Declarando Layout ....................................................................................................... 117
Escreve o XML ......................................................................................................... 118
Carregar os recursos XML ....................................................................................... 119
Atributos ................................................................................................................... 119
ID .......................................................................................................................... 119
Parmetros de layout ............................................................................................ 120
Posio de Layout ..................................................................................................... 122
Tamanho, padding e margin ..................................................................................... 122
Criando Menus ............................................................................................................. 124
Menu de Opes ................................................................................................... 124
Menu de Contexto ................................................................................................ 124
Submenu ............................................................................................................... 124
Criando um recurso de menu .................................................................................... 124
Inflar um recurso de menu ........................................................................................ 126
Criando um Menu de Opes ................................................................................... 126
Respondendo ao do usurio............................................................................ 127
Alterando os itens de menu em tempo de execuo ............................................. 129
Criando um Menu de Contexto ................................................................................ 129
ANDROID, uma viso geral Anderson Duarte de Amorim
6
Registre uma ListView ......................................................................................... 130
Criando Submenus .................................................................................................... 132
Outras funes do menu ........................................................................................... 132
Grupos de Menu ................................................................................................... 132
Itens de menu verificados ..................................................................................... 133
As teclas de atalho ................................................................................................ 135
Adicionar intenes em menu dinamicamente ..................................................... 136
Permitindo a sua atividade a ser adicionada para outros menus........................... 137
Usando a barra de ao ................................................................................................. 139
Adicionando a barra de ao .................................................................................... 139
Removendo a barra de ao .................................................................................. 140
Adicionando itens de ao ........................................................................................ 141
Usando o cone do aplicativo como um item de ao .......................................... 142
Usando o cone do aplicativo para navegar "para cima" ...................................... 143
Adicionando uma exibio de ao .......................................................................... 144
Adicionando abas ..................................................................................................... 146
Adicionando de navegao drop-down .................................................................... 149
Exemplo de SpinnerAdapter e OnNavigationListener ......................................... 150
Estilizando a barra de ao ....................................................................................... 152
Criando caixas de dilogo............................................................................................. 156
Mostrando uma caixa de dilogo .............................................................................. 156
Dispensar um dilogo ............................................................................................... 158
Usando demisso de receptores ............................................................................ 158
Criando um AlertDialog ........................................................................................... 159
Adicionando botes .............................................................................................. 160
Adicionando uma lista .......................................................................................... 161
Adicionando caixas de seleo e botes de rdio ................................................. 161
ANDROID, uma viso geral Anderson Duarte de Amorim
7
Criar um ProgressDialog .......................................................................................... 162
Mostrando uma barra de progresso ...................................................................... 163
Criando uma caixa de dilogo personalizada ........................................................... 166
Manipulando eventos de UI .......................................................................................... 169
Os ouvintes de eventos ............................................................................................. 169
Manipuladores de eventos ........................................................................................ 172
Modo de toque .......................................................................................................... 173
Manipulao do foco ................................................................................................ 174
Notificar o usurio ........................................................................................................ 176
Notificao brinde .................................................................................................... 176
Criando notificaes brinde .................................................................................. 177
Notificao na barra de status ................................................................................... 179
Criao de notificaes da barra de status ............................................................ 180
Notificao de dilogo .............................................................................................. 189
Aplicando estilos e temas ............................................................................................. 190
Definio de estilos .................................................................................................. 190
Herana ................................................................................................................. 191
Propriedades do estilo ........................................................................................... 192
Aplicando estilos e temas para a interface do usurio .............................................. 194
Aplicar um estilo a uma view ............................................................................... 194
Aplicar um tema a uma atividade ou aplicao .................................................... 195
Selecione um tema baseado na verso de plataforma........................................... 196
Usando estilos e temas da plataforma ...................................................................... 196
Recursos de aplicao ................................................................................................... 198
Armazenamento de dados ............................................................................................. 201
Utilizando preferncias compartilhadas ................................................................... 201
Preferncias do usurio ......................................................................................... 202
ANDROID, uma viso geral Anderson Duarte de Amorim
8
Usando o armazenamento interno ............................................................................ 203
Salvando os arquivos de cache ............................................................................. 204
Usando o armazenamento externo ............................................................................ 205
Verificar a disponibilidade dos meios .................................................................. 205
Acessando arquivos em armazenamento externo ................................................. 206
Escondendo seus arquivos a partir da Media Scanner .......................................... 206
Como salvar arquivos que devem ser compartilhados ......................................... 206
Salvando os arquivos de cache ............................................................................. 207
Utilizando bancos de dados ...................................................................................... 208
Banco de dados de depurao ............................................................................... 209
Usando uma conexo de rede ................................................................................... 209
Artigos .......................................................................................................................... 210
Acessibilidade ........................................................................................................... 210
Linguagens e recursos .......................................................................................... 210
Linguagens e localidade ....................................................................................... 211
Fazendo o dispositivo falar ................................................................................ 211
Interface .................................................................................................................... 213
Toque .................................................................................................................... 213
Gestos ....................................................................................................................... 216
Mtodo de entrada de dados ................................................................................. 216
Criando um mtodo de entrada de dados ............................................................. 223
Aes de desenhos .................................................................................................... 226
Truques de layout: criando layouts eficientes .......................................................... 229
Truques de layout: usando ViewStub ....................................................................... 234
Truques de layout: mesclando layouts...................................................................... 237
ListView, uma otimizao ........................................................................................ 244
Live folders ............................................................................................................... 247
ANDROID, uma viso geral Anderson Duarte de Amorim
9
Live Wallpapers ........................................................................................................ 252
Usando webViews .................................................................................................... 254
Funcionalidades ........................................................................................................ 255
Caixa de pesquisa ................................................................................................. 255
Sistema ..................................................................................................................... 258
Alocao de memria ........................................................................................... 258
Zipaling oferece uma otimizao fcil ................................................................. 260
Nota .............................................................................................................................. 263
Fontes ........................................................................................................................... 263
Fontes das imagens ................................................................................................... 266
Fontes dos artigos ..................................................................................................... 266


ANDROID, uma viso geral Anderson Duarte de Amorim
10
Introduo
O Android um software open-source criado para os celulares e outros dispositivos. O
Android Open Source Project (AOSP), liderado pelo Google, est encarregado da
manuteno e desenvolvimento do Android. Muitos fabricantes de dispositivos
trouxeram ao mercado de dispositivos rodando o Android, e eles so disponveis ao
redor do mundo.
O objetivo principal construir uma plataforma de software excelente para usurios de
todos os dias. Uma srie de empresas empenhou muitos engenheiros para atingir esse
objetivo, e o resultado uma produo total de produtos de consumo de qualidade, cuja
fonte aberta para customizao e portabilidade.
Voc pode encontrar mais informaes sobre o Android a partir destas pginas abaixo:
Filosofia de projeto e objetivos
Interagindo com o projeto
Compatibilidade com Android
Informaes sobre licenciamento
ANDROID, uma viso geral Anderson Duarte de Amorim
11
Atividades
Uma Activity um componente do aplicativo que fornece uma tela com a qual os
usurios podem interagir, a fim de fazer algo, como discar o telefone, tirar uma foto,
enviar um e-mail, ou ver um mapa. Para cada atividade dada uma janela na qual se
desenha sua interface de usurio. A janela normalmente preenche a tela, mas pode ser
menor do que a tela e flutuar em cima de outras janelas.
Um aplicativo normalmente consiste de mltiplas atividades que so frouxamente
ligadas uns aos outros. Normalmente uma atividade em um aplicativo especificada
como a atividade principal", que apresentada ao usurio ao iniciar o aplicativo pela
primeira vez. Cada atividade pode comear outra atividade, a fim de executar aes
diferentes. Cada vez que comea uma nova atividade, a atividade anterior
interrompida, mas o sistema preserva a atividade em uma pilha (a "pilha de volta").
Quando uma nova atividade comea, empurrada para a pilha de volta e leva o foco do
usurio. A pilha de volta usa "last in, first out" como mecanismo de fila, ento, quando
o usurio est em uma atividade e pressione a tecla BACK, a atividade removida da
pilha (e destruda) e retoma a atividade anterior.
Quando uma atividade parada por causa de uma nova atividade, h uma notificao da
alterao no estado atravs de mtodos de retorno da atividade do ciclo de vida.
Existem vrios mtodos de retorno que uma atividade possa receber, devido a uma
mudana em seu estado. Por exemplo, quando parado, sua atividade deve liberar todos
os objetos grandes, como conexes de rede ou banco de dados. Quando a atividade
recomea, voc pode readquirir os recursos necessrios e retomar as aes que foram
interrompidas. Estas transies de estado so todos parte do ciclo de atividade.
Criar uma atividade
Para criar uma atividade, voc deve criar uma subclasse da Activity (ou uma subclasse
existente do mesmo). Em sua subclasse, voc precisa implementar mtodos de callback
que chama o sistema quando ocorrem as transies de atividade entre diversos estados
do seu ciclo de vida, como quando a atividade est sendo criada, parou, recomeou, ou
foi destruda. Os dois mtodos de retorno mais importantes so:
onCreate(): Voc deve implementar este mtodo. O sistema chama isso ao criar a sua
atividade. Dentro de sua aplicao, voc deve inicializar os componentes essenciais de
ANDROID, uma viso geral Anderson Duarte de Amorim
12
sua atividade. Mais importante, este o lugar onde voc deve chamar setContentView()
para definir o layout para a atividade do usurio a interface.
onPause(): O sistema chama este mtodo como o primeiro indcio de que o usurio est
saindo de sua atividade (embora nem sempre signifique que a atividade est sendo
destruda). Isso geralmente onde voc deve cometer quaisquer alteraes que devem
ser mantidas para alm da sesso atual do usurio (porque o usurio pode no voltar).
Existem vrios mtodos de retorno do ciclo de vida de outros que voc deve usar a fim
de proporcionar uma experincia de usurio mais fluida entre as atividades e manipular
interrupes inesperadas que causem a sua atividade a ser interrompida e at mesmo
destruda.
Implementando uma interface de usurio
A interface de usurio para uma determinada atividade assegurada por uma hierarquia
de pontos de vista - objetos derivam da classe View. Cada exibio controla um
determinado espao retangular dentro da janela da atividade e pode responder a
interao do usurio. Por exemplo, uma viso pode ser um boto que inicia uma ao
quando o usurio toc-la.
Android fornece um nmero de pontos de vista prontos que voc pode usar para criar e
organizar seu layout. "Widgets" so vistas que proporcionam um visual (interativo) de
elementos para a tela, como um boto, um campo texto, checkbox, ou apenas uma
imagem. "Esquemas" so pontos de vista derivados de ViewGroup que fornecem um
modelo de layout exclusivo para a estrutura derivada, como um layout linear, um layout
de grade, ou a disposio relativa. Voc pode criar uma subclasse da View e
ViewGroup (ou subclasses existentes) para criar seus prprios widgets e layouts e
aplic-las ao seu layout atividade.
A maneira mais comum para definir um layout usando pontos de vista com um
arquivo XML salvo disposio em recursos do seu aplicativo. Dessa forma, voc pode
manter o design da sua interface de usurio separadamente do cdigo fonte que define o
comportamento da atividade. Voc pode definir o layout da interface do usurio para a
sua atividade com setContentView(), passando a identificao do recurso para o layout.
No entanto, voc tambm pode criar novas Views no seu cdigo de atividade e construir
ANDROID, uma viso geral Anderson Duarte de Amorim
13
uma hierarquia de vista atravs da insero de novos Views em um ViewGroup, em
seguida, usar esse esquema, passando a raiz ViewGroup para setContentView().
Declarando a atividade no manifesto
Voc deve declarar a sua atividade no arquivo de manifesto para que ele seja acessvel
para o sistema. Para declarar sua atividade, abra o arquivo e adicione um <activity>
como um filho do <application>. Por exemplo:
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
Existem vrios outros atributos que podem ser includos nesse elemento, para definir
propriedades, como o rtulo para a atividade, um cone para a atividade, ou um tema ao
estilo de interface do usurio da atividade.
O uso de filtros inteno
Um <activity> tambm pode especificar filtros diferentes, usando o <intent-filter>, a
fim de declarar como outros componentes de aplicao podem ativ-lo.
Quando voc cria um novo aplicativo usando as ferramentas do Android SDK, a
atividade de topo que criada para voc automaticamente inclui a inteno de filtro que
declara a atividade e responde ao "principal" e deve ser colocado no "lanador" da
categoria. A inteno parece filtro como este:
<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 este o "principal ponto de entrada" para o
aplicativo. O elemento <category> especifica que esta atividade deve ser listada no
sistema lanador de aplicao.
ANDROID, uma viso geral Anderson Duarte de Amorim
14
Se voc pretende que o seu aplicativo seja auto-suficiente e no permita que outras
aplicaes ativem as suas atividades, ento voc no precisa de nenhum outro filtro de
inteno. Apenas uma atividade deve ter a ao "principal" e "lanador" da categoria,
como no exemplo anterior. Atividades que voc no deseja disponibilizar para outros
aplicativos no devem ter a inteno de filtros e voc pode inici-los usando as
intenes explcitas.
No entanto, se voc quiser a sua atividade para responder s intenes implcitas que
so entregues a partir de outras aplicaes (e suas prprias), ento voc deve definir
filtros de inteno adicional para a sua atividade. Para cada tipo de inteno para o qual
pretende responder, voc deve incluir um <intent-filter> que inclui um elemento
<action> e, opcionalmente, um elemento <category> e/ou um <data>. Estes elementos
especificam o tipo de intenes para que sua atividade possa responder.
Iniciar uma atividade
Voc pode iniciar outra atividade, chamando startActivity(), passando-lhe uma Intent
que descreve a atividade que deseja iniciar. A inteno especifica qualquer atividade
exatamente o que deseja iniciar ou descreve o tipo de ao que deseja executar (e o
sistema seleciona a atividade adequada para voc, que pode mesmo ser de um aplicativo
diferente). A inteno tambm pode transportar pequenas quantidades de dados a serem
utilizados pela atividade que iniciada.
Quando se trabalha dentro de sua prpria aplicao, muitas vezes voc precisa
simplesmente lanar uma atividade conhecida. Voc pode fazer isso criando uma
inteno que define explicitamente a atividade que deseja iniciar, usando o nome da
classe. Por exemplo, aqui est como uma atividade inicia outra atividade denominada
SignInActivity:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
No entanto, sua aplicao pode tambm querer executar alguma ao, como enviar um
e-mail, mensagem de texto, ou atualizao de status, usando dados de sua atividade.
Neste caso, sua aplicao no pode ter as suas prprias atividades para realizar tais
aes, para que voc possa aproveitar ao invs das atividades previstas por outras
aplicaes no dispositivo, que pode executar as aes para voc. Este o lugar onde as
ANDROID, uma viso geral Anderson Duarte de Amorim
15
intenes so realmente valiosas, voc pode criar uma inteno que descreve uma ao
que deseja executar e o sistema inicia a atividade adequada a partir de outro aplicativo.
Se houver mltiplas atividades que podem manipular a inteno, ento o usurio pode
selecionar qual usar. Por exemplo, se voc quer permitir que o usurio envie uma
mensagem de e-mail, voc pode criar a seguinte inteno:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
O EXTRA_EMAIL extra adicionado uma matriz de seqncia de endereos de e-mail
para onde o e-mail deve ser enviado. Quando um aplicativo de e-mail responde a esta
inteno, ele l a matriz de cadeia prevista na extra e as coloca no campo "Para" do
formulrio de composio de e-mail.
Iniciar uma atividade para um resultado
s vezes, voc pode querer receber um resultado da atividade que voc comear. Nesse
caso, iniciar a atividade, chamando startActivityForResult() (em vez de startActivity() ).
Para ento receber o resultado da atividade subseqente, aplicar o onActivityResult(),
mtodo de retorno. Quando a atividade subseqente feita, ele retorna um resultado de
uma Intent para o seu mtodo onActivityResult().
Por exemplo, talvez voc queira que o usurio escolha um de seus contatos, para que
sua atividade pode fazer algo com as informaes desse contato. Veja como voc pode
criar uma inteno e manipular o resultado:
private void pickContact() {
// Create an intent to "pick" a contact, as defined by the 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) {
// If the request went well (OK) and the request was PICK_CONTACT_REQUEST
if (resultCode == Activity.RESULT_OK && requestCode ==
PICK_CONTACT_REQUEST) {
// Perform a query to the contact's content provider for the contact's name
Cursor cursor = getContentResolver().query(data.getData(),
new String[] {Contacts.DISPLAY_NAME}, null, null, null);
if (cursor.moveToFirst()) { // True if the cursor is not empty
int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
String name = cursor.getString(columnIndex);
ANDROID, uma viso geral Anderson Duarte de Amorim
16
// Do something with the selected contact's name...
}
}
}
Este exemplo mostra a lgica bsica que voc deve usar seu mtodo onActivityResult()
para lidar com um resultado de atividade. A primeira condio verifica se a solicitao
foi bem-sucedida, se for, ento o resultCode ser RESULT_OK e se a solicitao para
que este resultado est respondendo conhecido, neste caso, o requestCode coincide
com o segundo parmetro enviada com startActivityForResult(). De l, o cdigo
manipula o resultado de atividade, consultando os dados retornados de uma Intent.
O que acontece , um ContentResolver executa uma consulta contra um provedor de
contedo, que retorna um Cursor que permite que os dados consultados possam serem
lidos.
Encerrar uma atividade
Voc pode encerrar uma atividade chamando seu mtodo finish(). Voc tambm pode
encerrar uma atividade separada que j comeou chamando finishActivity() .
Nota: Na maioria dos casos, voc no deve terminar explicitamente uma atividade com
estes mtodos. Como discutido na seo seguinte sobre o ciclo de vida de atividade, o
sistema Android gerencia a vida de uma atividade para voc, ento voc no precisa
terminar a sua prpria atividade. Chamar esses mtodos pode afetar negativamente a
experincia do usurio e s deve ser usado quando voc realmente no quer que o
usurio retorne a esta instncia da atividade.
Gerenciando o ciclo de atividade
Gerenciar o ciclo de vida de suas atividades atravs da implementao de mtodos de
retorno essencial para desenvolver uma aplicao forte e flexvel. O ciclo de vida de
uma atividade est diretamente afetada pela sua associao com outras atividades, a sua
misso e voltar pilha.
Uma atividade pode existir em trs estados, essencialmente:
Retomado: A atividade est em primeiro plano da tela e tem o foco do usurio. (Esse
estado tambm por vezes referido como "run".)
ANDROID, uma viso geral Anderson Duarte de Amorim
17
Em pausa: Outra atividade est em primeiro plano e tem foco, mas este ainda visvel.
Ou seja, outra atividade visvel na parte superior de um presente e que a atividade
parcialmente transparente ou no cobre a tela inteira. Uma atividade em pausa est
completamente viva (o objeto Activity mantido na memria, ele mantm todas as
informaes do estado e membro, e permanece preso ao gerenciador de janelas), mas
pode ser morta pelo sistema em situaes de pouca memria.
Parado: A atividade totalmente obscurecida por outra atividade (a atividade est
agora em "background"). A atividade parada tambm est ainda viva (o objeto Activity
mantido na memria, ele mantm todas as informaes do estado e membro, mas no
est ligado ao gerenciador de janelas). No entanto, j no visvel para o usurio e pode
ser morto pelo sistema quando a memria necessria em outro lugar.
Se uma atividade est em pausa ou parada, o sistema pode retir-la da memria, quer
por pedir para terminar (chamando seu finish()), ou simplesmente matar o processo.
Quando a atividade aberta novamente (depois de ter sido concludo ou morto), ela
deve ser criada por toda parte.
Aplicar o ciclo de vida callbacks
Quando uma atividade transita entrando e saindo dos diferentes estados descritos acima,
ele notificado atravs de vrios mtodos de retorno. Todos os mtodos de callback so
ganchos que voc pode substituir para fazer um trabalho adequado quando o estado da
sua atividade muda. A atividade seguinte inclui cada um dos mtodos de ciclo de vida
fundamentais:
public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now "resumed").
}
ANDROID, uma viso geral Anderson Duarte de Amorim
18
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}
Nota: A implementao destes mtodos do ciclo de vida deve sempre chamar a
implementao da superclasse antes de fazer qualquer trabalho, conforme mostrado
nos exemplos acima.
Juntos, esses mtodos definem o ciclo de vida de uma atividade. Ao implementar esses
mtodos, voc pode monitorar trs loops aninhados no ciclo de vida de atividade:
A vida inteira de uma atividade acontece entre a chamada para onCreate() e a
chamada para onDestroy(). Sua atividade deve executar a instalao do "Estado"
global (tal como a definio de layout) em onCreate(), e liberar todos os recursos
remanescentes em onDestroy(). Por exemplo, se a sua atividade tem um
segmento em execuo em segundo plano para transferir os dados da rede, ele
pode criar esse tpico em onCreate() e depois parar o segmento em onDestroy().
O tempo de vida visvel de uma atividade acontece entre a chamada para
onStart() e a chamada para onStop(). Durante este tempo, o usurio pode ver a
atividade na tela e interagir com ele. Por exemplo, onStop() chamado quando
inicia uma nova atividade e esta no mais visvel. Entre estes dois mtodos,
voc pode manter os recursos que so necessrios para mostrar a atividade para
o usurio. Por exemplo, voc pode registrar um BroadcastReceiver em onStart()
para monitorar as mudanas que impactam sua interface do usurio, e cancelar o
registro em onStop() quando o usurio no pode mais ver o que voc est sendo
exibido. O sistema pode chamar onStart() e onStop() vrias vezes durante toda a
vida til da atividade, como a atividade se alterna entre visvel e oculta para o
usurio.
ANDROID, uma viso geral Anderson Duarte de Amorim
19
O tempo de vida do primeiro plano de uma atividade acontece entre a chamada
para onResume() e a chamada para onPause(). Durante este tempo, a atividade
est na frente de todas as outras atividades na tela e tem foco de entrada do
usurio. Uma atividade pode freqentemente transitar para dentro e fora do
plano, por exemplo, onPause() chamado quando o dispositivo vai dormir ou
quando uma caixa de dilogo aparece. O cdigo desses dois mtodos deve ser
bastante leve, para evitar transies lentas que fazem o usurio esperar.
A figura 1 ilustra esses laos e os caminhos de uma atividade que podem levar a esses
estados.

Figura 1. O ciclo de vida de atividade.
ANDROID, uma viso geral Anderson Duarte de Amorim
20
Tabela 1. Um resumo do ciclo de vida do callback mtodos atividade.
Mtodo Descrio
Killable
depois?
Seguinte
onCreate()

Chamado quando a atividade
criada pela primeira vez.
Isto onde voc deve fazer
tudo do seu conjunto esttico
normal - criar pontos de vista,
vincular dados em listas, e
assim por diante. Sempre
seguido por onStart() .
No onStart()
onRestart()

Chamado depois que a
atividade foi interrompida,
pouco antes de ele ser iniciado
novamente. Sempre seguido
por onStart()
No onStart()
onStart()

Chamado imediatamente antes
da atividade tornar-se visvel
para o usurio. Seguido por
onResume() se a atividade
vem para o primeiro plano, ou
onStop() se torna oculto.
No onResume()
onResume()
Chamado imediatamente antes
da atividade passar a interagir
com o usurio. Neste ponto, a
atividade est no topo da pilha
de atividade. Sempre seguido
por onPause() .
No onPause()

ANDROID, uma viso geral Anderson Duarte de Amorim
21
onPause()
Chamado quando o sistema
est prestes a comear a
retomar a outra atividade. Este
mtodo geralmente usado
para confirmar as alteraes
no salvas, dados persistentes,
animaes stop e outras coisas
que podem estar consumindo
CPU, e assim por diante. Ele
deve fazer tudo o que ele faz
muito rapidamente, porque a
prxima atividade no ser
retomada at que ele retorne.
Seguidas por onResume() se a
atividade retorna para a frente,
ou por onStop() se torna
invisvel para o usurio.
Sim
onResume() ou
onStop()
onStop()
Chamado quando a atividade
j no visvel para o usurio.
Isso pode acontecer porque
ele est sendo destrudo, ou
porque outra atividade (seja
um existente ou uma nova) foi
retomado e est cobrindo-o.
Seguidas por onRestart() se a
atividade est voltando para
interagir com o usurio, ou
por onDestroy() se essa
atividade est indo embora.
Sim
onRestart() ou
onDestroy()

ANDROID, uma viso geral Anderson Duarte de Amorim
22
onDestroy()
Chamado antes que a
atividade destruda. Esta a
chamada final que a atividade
ir receber.Poderia ser
chamada, quer porque a
atividade est acabando
(algum chamado finish()
nela), ou porque o sistema
est destruindo essa instncia
da atividade para economizar
espao. Voc pode distinguir
entre estes dois cenrios com
o isFinishing().
Sim nada
A coluna chamada "killable depois?" indica se o sistema pode matar o processo que
acolhe a atividade a qualquer momento aps o mtodo retornar, sem executar outra
linha. Trs mtodos so marcados como "sim": (onPause() , onStop() , e onDestroy() ).
onPause() o primeiro dos trs, uma vez que a atividade criada, onPause() o ltimo
mtodo que garantido para ser chamado antes que o processo pode ser morto, se o
sistema deve recuperar a memria em caso de emergncia, ento onStop() e onDestroy()
no podem ser chamados. Portanto, voc deve usar onPause() para escrever dados
persistentes para armazenamento. No entanto, voc deve ser seletivo sobre quais
informaes devem ser mantidas durante onPause(), porque os procedimentos de
bloqueio neste mtodo bloqueiam a passagem para a prxima atividade e retardam a
experincia do usurio.
Mtodos que so marcados como "No" na coluna killable protegem o processo da
atividade de ser morto desde o momento em que so chamados. Assim, uma atividade
killable a partir do momento onPause() e retorna quando onResume() chamado. No
ser novamente killable at onPause() seja novamente chamado e retornado.
Nota: uma atividade que no tecnicamente "killable" por esta definio na tabela 1
ainda pode ser morta pelo sistema, mas isso vai acontecer apenas em circunstncias
extremas, quando no h outro recurso.
ANDROID, uma viso geral Anderson Duarte de Amorim
23
Salvando estado de atividade
A introduo Gesto do Ciclo de Atividade menciona brevemente que, quando uma
atividade est em pausa ou parada, o estado da atividade mantido. Isto verdade
porque a Activity ainda est retida na memria quando est em pausa ou parada, todas
as informaes sobre seus membros e estado atuais ainda esto vivos. Assim, qualquer
alterao que o usurio fez no mbito da atividade retida na memria, de modo que
quando a atividade retorna para o primeiro plano (quando ele "retoma"), essas
mudanas ainda esto l.

Figura 2. As duas formas em que para a atividade um usurio retorna ao foco com seu estado intacto,
quer a atividade interrompida, e retomada em seguida, o estado de atividade permanece intacta (
esquerda), ou a atividade destrudo, ento recriada e a atividade deve restaurar o estado da atividade
anterior (direita).
No entanto, quando o sistema destri uma atividade, a fim de recuperar a memria, a
Activity destruda, ento o sistema no pode simplesmente continuar com o seu estado
intacto. Em vez disso, o sistema deve recriar a Activity se o usurio navega de volta
para ele. No entanto, o usurio no sabe que o sistema destri e recria a atividade e,
assim, provavelmente espera que a atividade seja exatamente como era. Nessa situao,
ANDROID, uma viso geral Anderson Duarte de Amorim
24
voc pode garantir que informaes importantes sobre o estado de atividade so
preservadas atravs da implementao de um mtodo de retorno adicional que permite
que voc salve as informaes sobre o estado de sua atividade e, em seguida, restaura
quando o sistema recria a atividade.
O mtodo de callback em que voc pode salvar informaes sobre o estado atual da sua
atividade onSaveInstanceState(). O sistema chama este mtodo antes de fazer a
atividade vulnervel a ser destruda e passa-lhe um objeto Bundle. O Bundle o lugar
onde voc pode armazenar informaes de estado sobre a atividade como pares valor-
nome, utilizando mtodos como putString(). Ento, se o sistema mata a atividade e o
usurio navega de volta para sua atividade, o sistema passa o Bundle para onCreate()
para que voc possa restaurar o estado de atividade que tenha sido guardado durante
onSaveInstanceState(). Se no h informaes do estado para restaurar, em seguida, o
Bundle que passou a onCreate() se torna nulo.
Nota: No h nenhuma garantia de que onSaveInstanceState() ser chamado antes de
sua atividade ser destruda, porque h casos em que no ser necessrio salvar o
estado (como quando o usurio deixa a sua atividade com a chave de volta, porque a
usurio explicitamente encerra as atividades). Se o mtodo for chamado, ele sempre
chamado antes de onStop() e, possivelmente, antes de onPause().
No entanto, mesmo se voc no faz nada e no implementar onSaveInstanceState(),
alguns estados de atividade so restaurados pela Activity de implementao padro da
classe de onSaveInstanceState(). Especificamente, a implementao padro chama
onSaveInstanceState() para cada View no layout, que permite fornecer informaes
sobre si que devem ser salvos. Quase todos os widgets no mbito Android implementam
este mtodo, de modo que qualquer mudana visvel para o interface do usurio so
automaticamente salvas e restauradas quando sua atividade recriada. Por exemplo, o
EditText salva qualquer texto digitado pelo usurio e o CheckBox widget salva se
marcado ou no. O nico trabalho exigido por voc fornecer uma identificao nica
(com o android:id) para cada elemento grfico que deseja salvar seu estado. Se um
elemento no tem um ID, ento ele no pode salvar seu estado.
Voc tambm pode parar explicitamente de salvar em seu layout seu estado, definindo o
android:saveEnabled para "false" ou chamando o setSaveEnabled(). Normalmente, voc
ANDROID, uma viso geral Anderson Duarte de Amorim
25
no deve desativar isso, mas voc pode caso queira restaurar o estado da atividade de
interface diferente.
Embora a implementao padro de onSaveInstanceState() salva as informaes teis
sobre a atividade da sua interface, voc ainda pode precisar substitu-lo para guardar
informaes adicionais. Por exemplo, voc talvez precise salvar valores de um membro
que mudou na vida da atividade (que poderiam se correlacionar com os valores
restaurados na interface do usurio, mas os membros que detm esses valores UI no
so restaurados, por padro).
Como a implementao padro de onSaveInstanceState() ajuda a salvar o estado da
interface do usurio, se voc substituir o mtodo para salvar informaes de estado
adicionais, voc deve sempre chamar a implementao da superclasse de
onSaveInstanceState() antes de fazer qualquer trabalho.
Nota: Devido ao onSaveInstanceState() no ser garantido de ser chamado, voc deve
us-lo apenas para registrar o estado transiente da atividade (o estado da interface do
usurio), voc nunca deve us-lo para armazenar dados persistentes. Em vez disso,
voc deve usar onPause() para armazenar dados persistentes (como os dados que
devem ser salvos em um banco de dados) quando o usurio deixa a atividade.
Uma boa maneira de testar a capacidade do seu aplicativo para restaurar seu estado
simplesmente girar o dispositivo para fazer alteraes na orientao da tela. Quando da
mudana de orientao da tela, o sistema destri e recria a atividade a fim de aplicar
recursos alternativos que possam estar disponveis para a nova orientao. Por esta
razo, muito importante para sua atividade restaurar completamente o seu estado
quando ele recriado, pois os usurios regularmente giram a tela ao usar aplicaes.
Manipulao de alteraes na configurao
Algumas configuraes de dispositivo podem mudar durante a execuo (tais como a
orientao da tela, a disponibilidade de teclado e idioma). Quando essa mudana ocorre,
o Android reinicia a atividade em execuo (onDestroy() chamado, seguido
imediatamente por onCreate()). O comportamento reiniciar projetado para ajudar a sua
candidatura a se adaptar s novas configuraes automaticamente recarregando a sua
aplicao com recursos alternativos que voc forneceu. Se voc projeta sua atividade
ANDROID, uma viso geral Anderson Duarte de Amorim
26
para lidar adequadamente com este evento, vai ser mais resistentes a eventos
inesperados no ciclo de atividade.
A melhor maneira de lidar com uma mudana de configurao, tais como uma mudana
na orientao da tela, simplesmente preservar o estado do seu aplicativo usando
onSaveInstanceState() e onRestoreInstanceState() (ou onCreate() ), como discutido na
seo anterior.
Coordenar as atividades
Quando uma atividade comea outra, ambas experimentam as transies do ciclo de
vida. A primeira atividade faz uma pausa e para (embora, no vai parar se ele ainda est
visvel ao fundo), enquanto a outra atividade criada. Caso esses dados compartilham
atividades salvas em disco ou em outro lugar, importante entender que a primeira
atividade no est completamente parada antes de a segunda ser criada. Pelo contrrio, o
processo de iniciar o segundo se sobrepe ao processo de parar o primeiro.
A ordem dos retornos do ciclo de vida bem definida, especialmente quando as duas
atividades esto no mesmo processo e est comeando um do outro. Aqui est a ordem
das operaes que ocorrem quando a atividade A comea atividade B:
1. O mtodo onPause() da atividade A executado.
2. Os mtodos onCreate(), onStart(), e onResume() de B so executados em
seqncia. (Atividade B agora tem o foco do usurio.)
3. Ento, se uma atividade no mais visvel na tela, a sua onStop() executada.
Esta seqncia previsvel de callbacks do ciclo de vida permite-lhe gerir a transio de
informaes de uma atividade para outra. Por exemplo, se voc deve escrever em um
banco de dados quando a primeira atividade pra para que esta atividade pode l-lo,
ento voc deve escrever para o banco de dados durante onPause() em vez de durante
onStop().

ANDROID, uma viso geral Anderson Duarte de Amorim
27
Fragmentos
Um Fragment representa um comportamento ou uma parte da interface de usurio em
uma Activity. Voc pode combinar vrios fragmentos em uma nica atividade para
construir uma interface multi-painel e reutilizao de um fragmento de atividades
mltiplas. Voc pode pensar em um fragmento como uma seo modular de uma
atividade, que tem seu prprio ciclo de vida, recebe os seus prprios eventos de entrada,
e que voc pode adicionar ou remover, enquanto a atividade est em execuo.
Um fragmento deve sempre ser incorporado em uma atividade e o ciclo de vida do
fragmento diretamente afetado pelo ciclo de vida da atividade de acolhimento. Por
exemplo, quando a atividade interrompida, assim so todos os fragmentos nele, e
quando a atividade destruda, assim so todos os fragmentos. No entanto, enquanto
uma atividade est em execuo (que na retomada do ciclo de vida do estado), voc
pode manipular cada fragmento de forma independente, como adicionar ou remover.
Quando voc executa uma operao deste tipo de fragmento, voc tambm pode
adicion-la a uma pilha de volta que gerenciado pela atividade de cada pilha de volta
na entrada da atividade que um registro da transao de fragmento que ocorreu. A
volta da pilha permite que o usurio possa reverter uma transao (navegar para trs),
pressionando a tecla BACK.
Quando voc adiciona um fragmento como uma parte do seu layout, ele vive em um
ViewGroup dentro da view de hierarquia e define o seu prprio layout de pontos de
vista. Voc pode inserir um fragmento em seu layout declarando o fragmento na
atividade de distribuio de arquivos, como <fragment>, ou a partir de seu cdigo de
aplicativo, adicionando-o a um j existente ViewGroup. No entanto, um fragmento no
obrigado a fazer parte do esquema de atividade, voc tambm pode utilizar um
fragmento como um trabalhador invisvel para a atividade.
Filosofia de design
Android apresenta fragmentos no Android 3.0 (API Level "Honeycomb"),
principalmente para apoiar projetos mais dinmicos e flexveis de interface do usurio
em telas grandes, como os Tablets. Como uma tela de tablet muito maior do que a de
um telefone, h mais espao para combinar e trocar os componentes de interface do
usurio. Fragmentos permitem tais projetos sem a necessidade de gerenciar mudanas
ANDROID, uma viso geral Anderson Duarte de Amorim
28
complexas hierarquia vista. Ao dividir o layout de uma atividade em fragmentos, voc
se torna capaz de modificar a aparncia da atividade em tempo de execuo e preservar
essas mudanas em uma pilha de volta que gerenciada pela atividade.
Por exemplo, um aplicativo de notcias pode usar um fragmento para mostrar uma lista
de artigos esquerda e outro fragmento para mostrar um artigo direita, ento os
fragmentos aparecem em uma atividade, lado a lado, e cada fragmento tem seu prprio
conjunto do ciclo de vida, mtodos callback e lidam com seus prprios eventos de
entrada do usurio. Assim, em vez de usar uma atividade para selecionar um artigo e
outra atividade para ler o artigo, o usurio pode selecionar um artigo e ler tudo dentro da
mesma atividade, conforme ilustrado na figura 1.

Figura 1. Um exemplo de como dois mdulos de interface do usurio que normalmente so separados em
duas atividades podem ser combinados em uma atividade, utilizando fragmentos.
Um fragmento deve ser um componente modular e reutilizvel em sua aplicao. Ou
seja, porque o fragmento define o seu prprio layout e seu prprio comportamento,
usando seu prprio ciclo de vida callbacks, voc pode incluir um fragmento em
mltiplas atividades. Isto especialmente importante porque permite adaptar a sua
experincia de usurio para diferentes tamanhos de tela. Por exemplo, voc pode incluir
vrios fragmentos de uma atividade apenas quando o tamanho da tela suficientemente
grande, e, quando no , lanar atividades distintas que utilizam diferentes fragmentos.
Por exemplo, para continuar com o aplicativo de notcia, a aplicao pode inserir dois
fragmentos da atividade, quando rodando em uma grande tela extra (um tablet, por
exemplo). No entanto, em um tamanho de tela normal (um telefone, por exemplo), no
h lugar suficiente para os dois fragmentos, de modo a Atividade A inclui somente o
fragmento para a lista de artigos, e quando o usurio seleciona um artigo, ele comea a
ANDROID, uma viso geral Anderson Duarte de Amorim
29
Atividade B, que inclui o fragmento para ler o artigo. Assim, a aplicao suporta os
padres de projeto sugerido na figura 1.
Criando um fragmento

Figura 2. O ciclo de vida de um fragmento (enquanto a sua atividade est em execuo).
ANDROID, uma viso geral Anderson Duarte de Amorim
30
Para criar um fragmento, voc deve criar uma subclasse de Fragment (ou uma subclasse
existente do mesmo). O cdigo da classe Fragment se parece muito com uma Activity.
Ele contm mtodos de retorno semelhante a uma atividade, como onCreate(), onStart(),
onPause(), e onStop(). Na verdade, se voc est convertendo uma aplicao Android
existentes para usar fragmentos, voc pode simplesmente mover o cdigo de mtodos
de retorno de sua atividade sobre os mtodos de retorno de seus respectivos fragmentos.
Normalmente, voc deve implementar pelo menos os mtodos do ciclo de vida a seguir:
onCreate(): O sistema chama isso ao criar o fragmento. Dentro de sua aplicao, voc
deve inicializar os componentes essenciais do fragmento que pretende manter quando o
fragmento pausado ou parado, ento retomado.
onCreateView(): O sistema chama isso quando est na hora de extrair o fragmento de
sua interface de usurio pela primeira vez. Para desenhar uma interface para o seu
fragmento, voc deve retornar um View a partir deste mtodo que a raiz do fragmento
do seu layout. Voc pode retornar nulo se o fragmento no fornece uma interface do
usurio.
onPause(): O sistema chama este mtodo como o primeiro indcio de que o usurio est
saindo do fragmento (embora nem sempre significa que o fragmento est sendo
destrudo). Isso geralmente onde voc deve cometer quaisquer alteraes que devem
ser mantidas para alm da sesso atual do usurio (porque o usurio pode no voltar).
A maioria dos aplicativos devem implementar pelo menos estes trs mtodos para cada
fragmento, mas existem vrios mtodos de retorno que voc tambm deve usar para
lidar com diferentes fases do ciclo de vida do fragmento. Todos os mtodos de retorno
do ciclo de vida so discutidos mais adiante, na seo sobre o manuseio do Ciclo de
Vida do fragmento.
Existem tambm algumas subclasses que voc pode querer estender:
DialogFragment
Mostra uma janela flutuante. Usar essa classe para criar uma caixa de dilogo uma boa
alternativa para usar os mtodos auxiliares de dilogo na Activity, porque voc pode
incorporar um fragmento de dilogo para a volta da pilha de fragmentos gerido pela
atividade, permitindo que o usurio retorne a um fragmento rejeitado.
ANDROID, uma viso geral Anderson Duarte de Amorim
31
ListFragment
Exibe uma lista de itens que so gerenciados por um adaptador (como um
SimpleCursorAdapter), semelhante ao ListActivity. Ele fornece diversos mtodos para
gerenciar uma lista, como o onListItemClick() de callback para manipular eventos de
clique.
PreferenceFragment
Exibe uma hierarquia de objetos Preference como uma lista, semelhante
PreferenceActivity. Isso til quando se cria um "settings" para sua aplicao.
Adicionando uma interface de usurio
Um fragmento normalmente usado como parte de uma atividade de interface de
usurio e contribui com a sua prpria disposio para a atividade.
Para fornecer um layout de um fragmento, voc deve implementar o onCreateView(),
que o sistema Android chama quando hora do fragmento ser desenhado no layout. A
implementao deste mtodo deve retornar um View que a raiz do fragmento do seu
layout.
Nota: Se o fragmento uma subclasse de ListFragment, a implementao padro
retorna um ListView de onCreateView(), ento voc no precisa implement-lo.
Para devolver um layout de onCreateView(), voc pode retir-lo a partir de um layout
de recursos definidos em XML e o desenvolve. Para ajud-lo a faz-lo, onCreateView()
fornece um LayoutInflater objeto.
Por exemplo, aqui est uma subclasse de Fragment que carrega um layout a partir da
example_fragment.xml:
public static class ExampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}

ANDROID, uma viso geral Anderson Duarte de Amorim
32
Criando um layout
No exemplo acima, R.layout.example_fragment uma referncia a um recurso chamado
layout example_fragment.xml salvo na aplicao dos recursos.
O parmetro passado para onCreateView() o pai ViewGroup (da atividade do layout),
em que o layout do fragmento ser inserido. O parmetro savedInstanceState um
Bundle que fornece dados sobre a instncia anterior do fragmento, se o fragmento est
sendo retomado.
O mtodo inflate() utiliza trs argumentos:
A identificao de recurso do layout que voc deseja inserir.
O ViewGroup ser o pai do layout j em utilizao. Passando o container
importante para que o sistema possa aplicar os parmetros de layout para o
modo de exibio raiz do layout inflado, especificado pela posio do pai em
que ele est indo.
Um booleano que indica se o layout desenvolvido dever ser anexado ao
ViewGroup (segundo parmetro) durante a chamada do procedimento inflate().
(Neste caso, isso falso, porque o sistema j est inserindo o layout inflado no
container de passagem verdade seria criar um grupo de vista redundantes no
layout final.)
Adicionando um fragmento de uma atividade
Normalmente, um fragmento contribui com uma parcela de UI para a atividade de
acolhimento, que incorporado como parte da hierarquia da viso da atividade de
conjunto. H duas maneiras com as quais voc pode adicionar um fragmento para o
layout de atividade:
Declare o fragmento dentro atividade de layout do arquivo.
Neste caso, voc pode especificar propriedades de layout para o fragmento como se
fosse uma exibio. Por exemplo, aqui est o arquivo de layout para uma atividade
com dois fragmentos:

ANDROID, uma viso geral Anderson Duarte de Amorim
33
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
O atributo android:name na <fragment> especifica o Fragment para instanciar no
layout.
Quando o sistema cria esse layout, ele instancia cada fragmento especificado no
layout e chama o onCreateView() para cada um, para recuperar o layout de cada
fragmento. O sistema insere a View retornada pelo fragmento diretamente no
local do elemento <fragment>.
Nota: Cada fragmento requer um identificador nico que o sistema pode usar
para restaurar o fragmento se a atividade for reiniciada (e que voc pode usar
para capturar o fragmento para realizar transaes, como remov-lo). Existem
trs formas para fornecer uma identificao de um fragmento:
o Fornea o android:id com um ID nico.
o Fornea o android:tag com uma string nica.
o Se voc no fornecer nenhum dos dois anteriores, o sistema
utiliza a identificao de exibio de recipiente.
Ou ento, programaticamente adicionar o fragmento de um j existente
ViewGroup .
A qualquer momento, enquanto sua atividade est sendo executada, voc pode
adicionar fragmentos ao seu layout. Voc s precisa especificar um ViewGroup para
colocar o fragmento.
ANDROID, uma viso geral Anderson Duarte de Amorim
34
Para fazer transaes em sua atividade (como adicionar, remover ou substituir um
fragmento), voc deve usar as APIs do FragmentTransaction. Voc pode obter uma
instncia de FragmentTransaction de sua Activity como esta:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
Voc pode ento adicionar um fragmento ao usar o mtodo add(), especificando o
fragmento a adicionar e a viso para inseri-lo. Por exemplo:
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
O primeiro argumento passado para add() o ViewGroup em que o fragmento deve
ser colocado, especificado por identificao do recurso, e o segundo parmetro o
fragmento a acrescentar.
Depois que voc fizer as alteraes com FragmentTransaction , voc deve chamar
commit() para que as alteraes tenham efeito.
Adicionando um fragmento sem uma interface de usurio (UI)
Os exemplos acima mostram como adicionar um fragmento de sua atividade, a fim de
fornecer uma interface do usurio. No entanto, voc tambm pode usar um fragmento
para fornecer um comportamento de fundo para a atividade sem a apresentao da
interface do usurio.
Para adicionar um fragmento sem uma interface de usurio, adicione o fragmento da
atividade usando add(Fragment, String) (fornecimento de uma nica seqncia de "tag"
para o fragmento, ao invs de um ID). Isso adiciona o fragmento, mas, porque no est
associada a um ponto de vista do layout atividade, ele no recebe uma chamada para
onCreateView(). Assim voc no precisa implementar esse mtodo.
Fornecendo uma tag string para o fragmento no estritamente para os fragmentos no-
UI. Voc tambm pode fornecer etiquetas de seqncia de fragmentos que possuem
uma interface de usurio, mas se o fragmento no possui uma interface de usurio, a tag
string o nico caminho para identific-lo. Se voc deseja obter o fragmento da
atividade posterior, voc precisa usar findFragmentByTag().
ANDROID, uma viso geral Anderson Duarte de Amorim
35
Gerenciando fragmentos
Para gerenciar os fragmentos em sua atividade, voc precisar usar FragmentManager.
Para obt-lo, chame getFragmentManager() em sua atividade.
Algumas coisas que voc pode fazer com FragmentManager incluem:
Obter fragmentos que existem na atividade, com findFragmentById() (para os
fragmentos que fornecem uma interface de usurio no layout de atividade) ou
findFragmentByTag() (para os fragmentos que fazem ou no uma interface do
usurio).
Retirar fragmentos da pilha, com popBackStack() (simulando um comando
BACK pelo usurio).
Registre-se um ouvinte de alterao de parte de trs da pilha, com
addOnBackStackChangedListener().
Conforme demonstrado na seo anterior, voc tambm pode usar FragmentManager
para abrir uma FragmentTransaction, que lhe permite realizar transaes, tais como
adicionar e remover fragmentos.
Executando transaes com fragmento
Uma das grandes novidades sobre o uso de fragmentos em sua atividade a capacidade
de adicionar, remover, substituir e realizar outras aes com eles, em resposta
interao do usurio. Cada conjunto de alteraes que comprometem a atividade
chamado de transao e voc pode executar um usando APIs em FragmentTransaction.
Voc tambm pode salvar cada transao na pilha gerenciada pela atividade, permitindo
ao usurio navegar para trs atravs das mudanas no fragmento (semelhante ao navegar
para trs por meio de atividades).
Voc pode adquirir uma instncia de FragmentTransaction do FragmentManager como
este:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Cada transao um conjunto de mudanas que se deseja realizar, ao mesmo tempo.
Voc pode configurar todas as alteraes que pretendem efetuar uma operao
ANDROID, uma viso geral Anderson Duarte de Amorim
36
determinada utilizando mtodos como add(), remove(), e replace(). Em seguida, para
aplicar a operao para a atividade, voc deve chamar commit().
Antes de chamar commit(), no entanto, voc pode querer chamar addToBackStack(), a
fim de acrescentar a operao a uma volta da pilha de transaes. Esta volta na pilha
gerida pela atividade e permite que ao usurio retornar ao estado de fragmento anterior,
pressionando a tecla BACK.
Por exemplo, aqui est como voc pode substituir um fragmento a outro e preservar o
estado anterior da pilha de volta:
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();
Neste exemplo, newFragment substitui qualquer fragmento (se houver) atualmente no
continer de layout identificado pelo R.id.fragment_container ID. Ao chamar
addToBackStack(), salvado na pilha de volta a operao para que o usurio possa
anular a operao e trazer de volta o fragmento anterior pressionando a tecla BACK.
Se voc adicionar vrias alteraes operao (como um outro add() ou remove()) e
chamar addToBackStack(), ento todas as mudanas aplicadas antes de chamar
commit() so adicionados volta da pilha como uma nica operao e a tecla BACK ir
inverter-los todos juntos.
A ordem na qual voc adiciona as alteraes em um FragmentTransaction no importa,
exceto:
Voc deve chamar commit() por ltimo.
Se voc est adicionando vrios fragmentos para o mesmo recipiente, ento a
ordem em que voc adicion-los determina a ordem em que aparecem na
hierarquia.
ANDROID, uma viso geral Anderson Duarte de Amorim
37
Se voc no chamar addToBackStack() quando voc executar uma operao que
remove um fragmento, em seguida, esse fragmento destrudo quando a transao for
confirmada e o usurio no pode navegar de volta para ela. Considerando que, se voc
chamar addToBackStack() quando da remoo de um fragmento, o fragmento
interrompido e ser retomado se o usurio navega de volta.
Dica: Para cada transao, voc pode aplicar uma animao de transio, chamando
setTransition() antes do commit().
Chamar commit() no executa a operao imediatamente. Em vez disso, ele agenda a
execuo no segmento da atividade de interface do usurio (a thread "main"), logo que
o segmento for capaz de faz-lo. Se necessrio, no entanto, voc pode chamar
executePendingTransactions() no seu segmento de interface do usurio para executar
imediatamente as operaes apresentadas por commit(). Fazer isso geralmente no
necessrio a menos que a transao uma dependncia para o emprego em outros
segmentos.
Cuidado: voc pode cometer uma transao usando commit() apenas antes da
atividade salvar seu estado (quando o usurio deixa a atividade). Se a tentativa for
cometer depois desse ponto, uma exceo ser lanada. Isso ocorre porque o estado,
aps a confirmao, pode ser perdido se a atividade precisa ser restaurada. Para as
situaes em que no tem problema voc perder o commit, use
commitAllowingStateLoss().
Comunicando-se com a atividade
Ainda que um Fragment seja implementado como um objeto que independente de uma
Activity e pode ser usado dentro de mltiplas atividades, uma determinada instncia de
um fragmento est diretamente ligada atividade que o contm.
Especificamente, o fragmento pode acessar a instncia Activity com getActivity() e
facilmente realizar tarefas como encontrar um ponto de vista do esquema de atuao:
View listView = getActivity().findViewById(R.id.list);
Da mesma forma, sua atividade pode chamar mtodos no fragmento atravs da
aquisio de uma referncia para o Fragment de FragmentManager, usando
findFragmentById() ou findFragmentByTag(). Por exemplo:
ANDROID, uma viso geral Anderson Duarte de Amorim
38
ExampleFragment fragment = (ExampleFragment)
getFragmentManager().findFragmentById(R.id.example_fragment);
Criar callbacks evento para a atividade
Em alguns casos, voc pode precisar de um fragmento de compartilhar eventos com a
atividade. Uma boa maneira de fazer isso definir uma interface de retorno no interior
do fragmento e exigem que a atividade de acolhimento implemente-a. Quando a
atividade recebe uma chamada atravs da interface, ela pode compartilhar a informao
com outros fragmentos no layout conforme necessrio.
Por exemplo, se um aplicativo de notcias tem dois fragmentos de uma atividade e um
mostra uma lista de artigos (fragmento A) e outro mostra um artigo (fragmento B),
ento um fragmento deve informar a atividade quando um item da lista escolhido de
modo que pode dizer ao fragmento B para exibir o artigo. Neste caso, a interface
OnArticleSelectedListener declarada dentro de um fragmento:
public static class FragmentA extends ListFragment {
...
// Container Activity must implement this interface
public interface OnArticleSelectedListener {
public void onArticleSelected(Uri articleUri);
}
...
}
Em seguida, a atividade que hospeda o fragmento implementa a
OnArticleSelectedListener e substitui onArticleSelected() para notificar o fragmento B
do evento a partir do fragmento A. Para garantir que a atividade de acolhimento
implemente essa interface, um fragmento do mtodo onAttach() de retorno (que chama
o sistema quando adicionando o fragmento para a atividade) instancia uma instncia de
OnArticleSelectedListener pelo casting da Activity que passado para onAttach():
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement
OnArticleSelectedListener");
}
ANDROID, uma viso geral Anderson Duarte de Amorim
39
}
...
}
Se a atividade no tenha aplicado a interface, ento o fragmento lana um
ClassCastException. Em caso de sucesso, o membro mListener mantm uma referncia
para a implementao da atividade de OnArticleSelectedListener, de modo que um
fragmento pode compartilhar eventos com a atividade, chamando os mtodos definidos
pela interface OnArticleSelectedListener. Por exemplo, se um fragmento uma
extenso do ListFragment, cada vez que o usurio clica em um item da lista, o sistema
chama onListItemClick() no fragmento, o que chama onArticleSelected() para
compartilhar o evento com a atividade:
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Append the clicked item's row ID with the content provider Uri
Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
// Send the event and Uri to the host activity
mListener.onArticleSelected(noteUri);
}
...
}
O parmetro id passado para onListItemClick() o ID da linha do item clicado, que a
atividade (ou outro fragmento) utiliza para buscar o artigo a partir do aplicativo
ContentProvider.
Adicionando itens barra de ao
Seus fragmentos podem contribuir itens de menu para a atividade do menu de opes (e,
conseqentemente, a Barra de ao) pela execuo onCreateOptionsMenu(). Para que
esse mtodo receba chamadas, no entanto, voc deve chamar setHasOptionsMenu()
durante onCreate(), para indicar que o fragmento gostaria de adicionar itens ao menu de
opes (caso contrrio, o fragmento no ir receber uma chamada para
onCreateOptionsMenu()).
Os itens que voc adicionar ao menu de opes do fragmento so acrescentados aos
itens de menu existente. O fragmento tambm recebe callbacks para
onOptionsItemSelected() quando um item de menu selecionado.
ANDROID, uma viso geral Anderson Duarte de Amorim
40
Voc tambm pode registrar uma exibio em seu layout para fornecer um menu de
contexto, chamando registerForContextMenu(). Quando o usurio abre o menu de
contexto, o fragmento recebe uma chamada para onCreateContextMenu(). Quando o
usurio seleciona um item, o fragmento recebe uma chamada para
onContextItemSelected().
Nota: Embora o fragmento receba um on-item-selected na chamada de retorno para
cada item de menu que acrescenta, a atividade a primeira a receber o respectivo
retorno quando o usurio seleciona um item de menu. Se a execuo da atividade da
chamada de retorno no item selecionado no lidar com o item selecionado, o evento
transmitido para retorno do fragmento. Isso verdadeiro para o menu de opes e
menus de contexto.
Manuseio do ciclo de vida do fragmento

Figura 3. O ciclo de vida afeta a atividade do ciclo de vida do fragmento.
ANDROID, uma viso geral Anderson Duarte de Amorim
41
Gerenciar o ciclo de vida de um fragmento um pouco como gerir o ciclo de vida de
uma atividade. Como uma atividade, um fragmento pode existir em trs estados:
Retomado: O fragmento visvel na atividade de execuo.
Em pausa: Outra atividade est em primeiro plano e tem o foco, mas a atividade em que
vive esse fragmento ainda visvel (a atividade do primeiro plano parcialmente
transparente ou no cobre a tela inteira).
Parado: O fragmento no visvel. A atividade host foi parada ou o fragmento foi
retirado da atividade, mas adicionado volta da pilha. Um fragmento que parou ainda
est vivo (todas as informaes do estado e membro so mantidas pelo sistema). No
entanto, j no visvel para o usurio e sero mortos se a atividade morta.
Tambm como uma atividade, voc pode manter o estado de um fragmento com um
Bundle, no caso de a atividade do processo ser morta e voc precisar restaurar o estado
do fragmento, quando a atividade recriada. Voc pode salvar o estado durante o
fragmento onSaveInstanceState() de callback e restaur-lo durante onCreate(),
onCreateView() ou onActivityCreated().
A diferena mais significativa no ciclo de vida entre uma atividade e um fragmento
como so armazenados em suas respectivas pilhas. Uma atividade colocada em uma
pilha de volta das atividades que gerido pelo sistema quando ela est parada, por
padro (para que o usurio possa navegar de volta a ele com a chave de volta, como
discutido em Tarefas e pilha de volta). No entanto, um fragmento colocado em uma
pilha de volta gerido pela atividade de acolhimento somente quando voc solicitar
explicitamente que a instncia deve ser salva chamando addToBackStack() durante uma
operao que remove o fragmento.
Gerenciar o ciclo de vida do fragmento muito semelhante gesto do ciclo de vida da
atividade. Assim, as mesmas prticas de gesto do ciclo de vida de atividade tambm se
aplicam aos fragmentos. O que voc tambm precisa entender, porm, como a vida da
atividade afeta a vida do fragmento.
Coordenao com o ciclo de vida de atividade
O ciclo de vida da atividade em que o fragmento de vida afeta diretamente o ciclo de
vida do fragmento, da mesma forma que cada ciclo de retorno para a atividade resulta
ANDROID, uma viso geral Anderson Duarte de Amorim
42
em um retorno semelhante para cada fragmento. Por exemplo, quando a atividade
recebe onPause(), cada fragmento na atividade recebe onPause().
Fragmentos tm alguns retornos do ciclo de vida extra, no entanto, para lidar com uma
interao nica com a atividade, a fim de realizar aes como construir e destruir UI do
fragmento. Estes mtodos de callback adicionais so:
onAttach(): Chamado quando o fragmento foi associado com a atividade.
onCreateView(): Chamado para criar a hierarquia de viso associada com o fragmento.
onActivityCreated(): Chamado quando onCreate() da atividade foi retornado.
onDestroyView(): Chamado quando a hierarquia de viso associada com o fragmento
est sendo removida.
onDetach(): Chamado quando o fragmento est sendo dissociado da atividade.
O fluxo do ciclo de vida de um fragmento, como ele afetado por sua atividade de
acolhimento, ilustrado pela figura 3. Nesta figura, voc pode ver o que cada estado
sucessivo da atividade que determina os mtodos de retorno de um fragmento pode
receber. Por exemplo, quando a atividade tenha recebido uma onCreate() de callback,
um fragmento da atividade no recebe mais do que o onActivityCreated() de callback.
Uma vez que a atividade atinge o estado retomado, voc pode adicionar livremente e
remover fragmentos na a atividade. Assim, somente quando a atividade est em estado
de retomada, o ciclo de vida de um fragmento pode mudar de forma independente.
No entanto, quando a atividade deixa o estado de retomada, o fragmento novamente
inserido atravs do ciclo de vida da atividade.

ANDROID, uma viso geral Anderson Duarte de Amorim
43
Loaders
Loaders tornam fcil carregar os dados de forma assncrona, em uma atividade ou um
fragmento. Loaders tm estas caractersticas:
Eles esto disponveis para cada Activity e Fragment.
Eles fornecem carga assncrona de dados.
Eles monitoram a fonte de seus dados e entregam novos resultados quando muda
o contedo.
Eles reconectam automaticamente o cursor do gestor passado, quando est sendo
recriado aps uma mudana de configurao. Assim, eles no precisam de voltar
a consultar os seus dados.
Resumo API Loader
Existem vrias classes e interfaces que podem ser envolvidos na utilizao de
carregadores em um aplicativo. Os resultados esto resumidos nesta tabela:
Classe/Interface Descrio
LoaderManager Uma classe abstrata associada a uma Activity ou
Fragment para gerenciar uma ou mais instncias
Loader. Isso ajuda a gerenciar um pedido de
execuo de operaes j em conjunto com o ciclo
de vida de Activity ou Fragment, o uso mais
comum deste com um CursorLoader, no entanto
as aplicaes so livres para escrever seus prprios
loaders para carregar outros tipos de dados.
H apenas um LoaderManager por atividade ou
fragmento. Mas um LoaderManager pode ter
vrios carregadores.
LoaderManager.LoaderCallbacks Uma interface de retorno de um cliente para
interagir com o LoaderManager. Por exemplo,
voc usar o onCreateLoader() para criar um
carregador novo.
ANDROID, uma viso geral Anderson Duarte de Amorim
44
Loader Uma classe abstrata que executa o carregamento
assncrono de dados. Esta a classe base para um
gestor. Voc usaria normalmente CursorLoader,
mas voc pode implementar sua prpria subclasse.
Enquanto os carregadores esto ativos, eles devem
acompanhar a fonte de seus dados e apresentar
resultados novos quando alterar o contedo.
AsyncTaskLoader Carregador abstrato que prov AsyncTansk para o
trabalho.
CursorLoader Uma subclasse de AsyncTaskLoader que consulta
o ContentResolver e retorna um Cursor. Essa
classe implementa o protocolo Loader de uma
forma padro para consultar cursores, com base
em AsyncTaskLoader para realizar a consulta de
cursor em uma discusso de fundo para que ele
no bloqueie os aplicativo de interface do usurio.
Utilizar este carregador a melhor maneira de
carregar os dados de forma assncrona a partir de
um ContentProvider, ao invs de realizar uma
consulta gerida atravs do fragmento ou de APIs.
As classes e interfaces na tabela acima so os componentes essenciais que voc vai usar
para implementar um carregador em sua aplicao. Voc no vai precisar de todos eles
para cada gestor, mas voc sempre precisa de uma referncia ao LoaderManager para
inicializar um carregador e uma implementao de um Loader, como CursorLoader. As
sees a seguir mostram como usar essas classes e interfaces em uma aplicao.
Usando carregadores em um aplicativo
Um aplicativo que usa carregadores normalmente inclui o seguinte:
Uma Activity ou Fragment.
Uma instncia da LoaderManager.
ANDROID, uma viso geral Anderson Duarte de Amorim
45
Um CursorLoader para carregar dados apoiado por uma ContentProvider.
Alternativamente, voc pode implementar sua prpria subclasse de Loader ou
AsyncTaskLoader para carregar dados de alguma outra fonte.
Uma implementao para LoaderManager.LoaderCallbacks. Isto onde voc
cria novos loaders e gerencia suas referncias aos carregadores existentes.
Uma maneira de mostrar o carregador de dados, como um
SimpleCursorAdapter.
Uma fonte de dados, como um ContentProvider, ao usar um CursorLoader .
Iniciando um Loader
O LoaderManager gerencia um ou mais instncias Loader dentro de uma Activity ou
Fragment. H apenas um LoaderManager por atividade ou fragmento.
Normalmente, voc inicializa um Loader com o mtodo onCreate() dentro da atividade
ou mtodo onActivityCreated() dentro do fragmento. Voc pode fazer isso da seguinte
forma:
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
O mtodo initLoader() utiliza os seguintes parmetros:
Um ID exclusivo que identifica o carregador. Neste exemplo, a identificao 0.
Os argumentos opcionais para fornecer ao loader a construo (null neste
exemplo).
A execuo de LoaderManager.LoaderCallbacks, em que a LoaderManager
chamada para relatar eventos carregador. Neste exemplo, a classe local
implementa a interface LoaderManager.LoaderCallbacks, assim que passa uma
referncia para si, this.

ANDROID, uma viso geral Anderson Duarte de Amorim
46
A chamada ao initLoader() assegura que um carregador inicializado e ativo. Ele tem
dois resultados possveis:
Se o carregador especificado pelo ID j existe, o ltimo carregador criado
reutilizado.
Se o carregador especificado pela ID no existir, initLoader() aciona o mtodo
LoaderManager.LoaderCallbacks em onCreateLoader(). Isto onde voc
implementa o cdigo para instanciar e retornar um carregador novo.
Em ambos os casos, a aplicao determinada LoaderManager.LoaderCallbacks est
associada com o carregador, e ser chamada quando o estado muda carregador. Se no
momento da chamada, o chamador est em seu estado inicial e o carregador solicitado
j existe e tem gerado os seus dados, o sistema solicita onLoadFinished() (durante
initLoader()), ento voc deve estar preparado para isso acontecer.
Observe que o mtodo initLoader() retorna o Loader que criado, mas voc no precisa
capturar uma referncia a ele. O LoaderManager gerencia a vida do carregador
automaticamente. O LoaderManager inicia e pra de carregar quando necessrio, e
mantm o estado do carregador e do seu contedo associado. Isso implica que voc
raramente interage com carregadores diretamente. mais comumente usar o
LoaderManager.LoaderCallbacks para intervir no processo de carregamento quando
ocorrem eventos especficos.
Reiniciando o Loader
Quando voc usa initLoader(), como mostrado acima, ele usa um carregador existente
com a identificao especificada, se houver. Se no houver, ele cria um. Mas s vezes
voc deseja descartar os dados antigos e comear de novo.
Para descartar os dados antigos, use restartLoader(). Por exemplo, essa implementao
de SearchView.OnQueryTextListener reinicia o carregador quando o usurio muda de
consulta. O loader precisa ser reiniciado para que ele possa usar a pesquisa de reviso de
filtro para fazer uma nova consulta:

ANDROID, uma viso geral Anderson Duarte de Amorim
47
public boolean onQueryTextChanged(String newText) {
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
getLoaderManager().restartLoader(0, null, this);
return true;
}
Usando callbacks do LoaderManager
LoaderManager.LoaderCallbacks uma interface de callback que permite que um
cliente interaja com o LoaderManager .
Loaders, em especial o CursorLoader, so esperados para reter seus dados depois de ser
interrompido. Isso permite aos aplicativos que mantenham seus dados atravs dos
mtodos onStop() e onStart() da atividade ou fragmento, de modo que quando os
usurios retornam a um pedido, eles no tem que aguardar os dados para recarregarem.
Voc usa o mtodo LoaderManager.LoaderCallbacks quando quer saber quando criar
um carregador novo, e para dizer a aplicao quando hora de parar de usar um
gerenciador de dados.
LoaderManager.LoaderCallbacks inclui os seguintes mtodos:
onCreateLoader() - instancia e retorna um novo Loader para o ID dado.
onLoadFinished() - Chamado quando um loader criado anteriormente terminou
sua carga.
onLoaderReset() - Chamado quando um loader criado anteriormente est sendo
redefinido, tornando os dados disponveis.
Esses mtodos so descritos em detalhes nas sees seguintes.
onCreateLoader
Quando voc tenta acessar um loader (por exemplo, atravs initLoader()), ele verifica se
o carregador especificado pelo ID existe. Se isso no ocorrer, ele aciona o mtodo
onCreateLoader() do LoaderManager.LoaderCallbacks. Isto onde voc ir criar um
carregador novo. Normalmente, esse ser um CursorLoader, mas voc pode
implementar sua prpria subclasse Loader.
ANDROID, uma viso geral Anderson Duarte de Amorim
48
Neste exemplo, o onCreateLoader() cria um mtodo de retorno CursorLoader. Voc
deve construir o CursorLoader usando o mtodo construtor, que exige um conjunto
completo de informaes necessrias para realizar uma consulta para o
ContentProvider. Especificamente, necessrio:
URI - A URI para o contedo para recuperar.
projeo - uma lista de quais colunas retornar. Passando null ir retornar todas
as colunas, que ineficiente.
seleo - Um filtro que declara que as linhas de retorno, formatado como uma
clusula WHERE SQL (excluindo o prprio WHERE). Passando null retornar
todas as linhas para o URI especificado.
selectionArgs - Voc pode incluir ?s na seleo, que sero substitudas pelos
valores da selectionArgs, na ordem em que aparecem na seleo. Os valores
sero vinculados como Strings.
SortOrder - Como adquirir as linhas, formatado como uma clusula ORDER BY
de SQL (excluindo-se o ORDER BY). Passando null usar a ordem de
classificao padro, que pode ser desordenada.
// If non-null, this is the current filter the user has provided.
String mCurFilter;
...
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = Contacts.CONTENT_URI;
}

// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ Contacts.DISPLAY_NAME + " != '' ))";
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); }
ANDROID, uma viso geral Anderson Duarte de Amorim
49
onLoadFinished
Este mtodo chamado quando um loader criado anteriormente terminou sua carga.
Este mtodo garantido para ser chamado antes do lanamento do ltimo dado que foi
fornecido para este carregador. Neste ponto, voc deve remover todo uso dos dados
antigos (desde que ser lanado em breve), mas no deve fazer a seu prprio
lanamento dos dados desde o seu carregador o dono e vai cuidar disso.
O carregador vai lanar os dados, uma vez que conhece que o aplicativo no est mais
usando. Por exemplo, se os dados so um cursor de um CursorLoader, voc no deve
chamar close() sobre ele mesmo. Se o cursor est sendo colocado em um
CursorAdapter, voc deve usar o mtodo swapCursor() para que o antigo Cursor no
seja fechado. Por exemplo:
// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;
...

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
}
onLoaderReset
Este mtodo chamado quando um loader criado anteriormente est sendo redefinido,
tornando os seus dados indisponveis. Este retorno permite saber quando o dado est
prestes a ser liberado assim voc pode remover a referncia a ele.
Esta aplicao chama swapCursor() com um valor null:
// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;
...

public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}

ANDROID, uma viso geral Anderson Duarte de Amorim
50
Exemplo
Como exemplo, aqui a implementao completa de um Fragment que apresenta um
ListView com os resultados de uma consulta contra o provedor de contedo contatos.
Ele usa um CursorLoader para gerenciar a consulta do fornecedor.
Para uma aplicao para acessar os contatos de um usurio, como mostrado neste
exemplo, o manifesto deve incluir a permisso READ_CONTACTS .
public static class CursorLoaderListFragment extends ListFragment
implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {

// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;

// If non-null, this is the current filter the user has provided.
String mCurFilter;

@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText("No phone numbers");

// We have a menu item to show in action bar.
setHasOptionsMenu(true);

// Create an empty adapter we will use to display the loaded data.
mAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_2, null,
new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
new int[] { android.R.id.text1, android.R.id.text2 }, 0);
setListAdapter(mAdapter);

// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
}

@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Place an action bar item for searching.
MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView sv = new SearchView(getActivity());
sv.setOnQueryTextListener(this);
item.setActionView(sv);
}

public boolean onQueryTextChange(String newText) {
ANDROID, uma viso geral Anderson Duarte de Amorim
51
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
getLoaderManager().restartLoader(0, null, this);
return true;
}

@Override public boolean onQueryTextSubmit(String query) {
// Don't care about this.
return true;
}

@Override public void onListItemClick(ListView l, View v, int position, long id) {
// Insert desired behavior here.
Log.i("FragmentComplexList", "Item clicked: " + id);
}

// These are the Contacts rows that we will retrieve.
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
Contacts._ID,
Contacts.DISPLAY_NAME,
Contacts.CONTACT_STATUS,
Contacts.CONTACT_PRESENCE,
Contacts.PHOTO_ID,
Contacts.LOOKUP_KEY,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = Contacts.CONTENT_URI;
}

// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ Contacts.DISPLAY_NAME + " != '' ))";
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
mAdapter.swapCursor(data);
}
ANDROID, uma viso geral Anderson Duarte de Amorim
52

public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
mAdapter.swapCursor(null);
}
}


ANDROID, uma viso geral Anderson Duarte de Amorim
53
Tarefas e pilha de execuo
Um aplicativo normalmente contm vrias atividades. Cada atividade deve ser
concebida em torno de um tipo especfico de ao que o usurio pode realizar e pode
iniciar outras atividades. Por exemplo, um aplicativo de e-mail pode ter uma atividade
para mostrar uma lista de e-mail. Quando o usurio seleciona um e-mail, uma nova
atividade aberta para ver o e-mail.
Uma atividade pode at iniciar atividades que existem em outras aplicaes no
dispositivo. Por exemplo, se sua aplicao quer enviar um e-mail, voc pode definir a
inteno de realizar um "send" e incluir alguns dados, tais como um endereo de e-mail
e uma mensagem. Uma atividade de outra aplicao que se declara para lidar com este
tipo de inteno, em seguida, aberta. Neste caso, a inteno enviar um e-mail, assim
a atividade de "compor" e-mail comea (se mltiplas atividades apiam a mesma
inteno, ento o sistema permite ao usurio selecionar qual usar). Quando o email
enviado, sua atividade retomada e parece como se a atividade de e-mail parte do seu
aplicativo. Mesmo que as atividades podem ser de diferentes aplicaes, o Android
mantm essa experincia do usurio uniforme, mantendo as duas atividades na mesma
tarefa.
Uma tarefa um conjunto de atividades que os usurios interagem ao realizar um
determinado trabalho. As atividades so organizadas em uma pilha (a "pilha de volta"),
na ordem em que cada atividade aberta.
A tela inicial o ponto de partida para a maioria das tarefas. Quando o usurio toca num
cone na tela do aplicativo (ou um atalho na tela inicial), essa tarefa vem para o primeiro
plano. Se existe uma tarefa para a aplicao (o pedido no tenha sido usado
recentemente), ento uma nova tarefa criada e a atividade "principal" abre como a
atividade da raiz na pilha.
Quando a atividade atual comea outra, a nova atividade empurrada na parte superior
da pilha e ganha foco. A atividade anterior permanece na pilha, mas est parada.
Quando uma atividade termina, o sistema mantm o estado atual de sua interface de
usurio. Quando o usurio pressiona a tecla BACK, a atividade atual retirada da parte
superior da pilha (a atividade destruda) e a atividade anterior recomea (o estado
anterior de sua interface restaurado). Atividades na pilha nunca so reorganizadas, s
ANDROID, uma viso geral Anderson Duarte de Amorim
54
includas e excludas da pilha - inseridas na pilha quando iniciado pela atividade atual e
retiradas quando o usurio deixa-as usando a tecla BACK. Como tal, a parte de trs da
pilha funciona como uma estrutura de objetos "last in, first out". A Figura 1 mostra esse
comportamento com uma linha do tempo mostrando o progresso entre as atividades
junto com a atual pilha de volta em cada momento.

Figura 1. Uma representao de como cada nova atividade em uma tarefa adiciona um item na parte de
trs da pilha. Quando o usurio pressiona a tecla BACK, a atividade atual destruda e volta atividade
anterior.
Se o usurio continuar a pressionar BACK, ento cada atividade da pilha retirada para
revelar a anterior, at que o usurio retorna tela inicial (ou de qualquer atividade que
estava sendo executada quando a tarefa comeou). Quando todas as atividades so
removidas da pilha, a tarefa no existe mais.

Figura 2. Duas tarefas tarefa esto no fundo, esperando para ser retomado, enquanto a Tarefa B recebe
interao do usurio em primeiro plano.
ANDROID, uma viso geral Anderson Duarte de Amorim
55

Figura 3. A nica atividade instanciada vrias vezes.
Uma tarefa uma unidade coesa, que pode passar para o "background" quando os
usurios comeam uma nova tarefa ou vo para a tela inicial, atravs da tecla HOME.
Enquanto no fundo, todas as atividades na tarefa esto paradas, mas a pilha de volta
para a tarefa permanece intacta, a tarefa simplesmente perdeu o foco enquanto outra
tarefa se realiza como mostrado na figura 2. Uma tarefa pode, em seguida, voltar ao
"primeiro plano" para que os usurios possam continuar de onde pararam. Suponha, por
exemplo, que a tarefa atual (Tarefa A) tenha trs atividades em sua pilha e dois no
mbito da atividade corrente. O usurio pressiona a tecla HOME, e em seguida, inicia
uma nova aplicao a partir do lanador de aplicao. Quando a tela inicial aparece,
uma tarefa vai para o fundo. Quando inicia o novo aplicativo, o sistema inicia uma
tarefa para a aplicao (Tarefa B) com sua prpria pilha de atividades. Aps a interao
com esse aplicativo, o usurio volta para HOME novamente e seleciona o aplicativo que
originalmente comeou Tarefa A. Agora, a tarefa A vem para o primeiro plano - todas
as trs atividades em sua pilha esto intactas e as atividades no topo da pilha so
retomadas. Neste ponto, o usurio tambm pode voltar Tarefa B indo para a HOME e
selecionando o cone do aplicativo que iniciou essa tarefa (ou tocando e segurando a
tecla HOME para revelar as tarefas recentes e selecionando uma). Este um exemplo
de multitarefa no Android.
Nota: Vrias tarefas podem ser realizadas no fundo de uma vez. No entanto, se o
usurio estiver executando muitas tarefas em segundo plano ao mesmo tempo, o
sistema pode comear a destruir as atividades do fundo, a fim de recuperar a memria,
fazendo com que os estados de atividade possam ser perdidos.
Como as atividades na parte de trs da pilha nunca so reorganizadas, se seu aplicativo
permite que usurios iniciem uma atividade especfica de mais de uma atividade, uma
ANDROID, uma viso geral Anderson Duarte de Amorim
56
nova instncia daquela atividade criada e colocada na pilha (ao invs de trazer
qualquer instncia anterior da atividade para o topo). Como tal, uma atividade em seu
aplicativo pode ser instanciada vrias vezes (mesmo de diferentes tarefas), como
mostrado na figura 3. Como tal, se o usurio navega para trs usando a tecla BACK,
cada instncia da atividade revelada na ordem em que foi aberta (cada um com seu
estado prprio de UI). No entanto, voc pode modificar esse comportamento se voc
no quer uma atividade a ser instanciada mais de uma vez.
Para resumir o comportamento padro de atividades e tarefas:
Quando a atividade A comea atividade B, uma atividade interrompida, mas o
sistema mantm o seu estado (como a posio de rolagem e texto inseridos em
formulrios). Se o usurio pressiona a tecla de volta, enquanto na Atividade B, a
atividade A continua com o seu estado restaurado.
Quando o usurio deixa uma tarefa, pressionando a tecla HOME, a atividade em
curso interrompida e sua tarefa vai para o fundo. O sistema mantm o estado
de cada atividade na tarefa. Se o usurio depois recomea a tarefa de selecionar
o cone do lanador, que comeou a tarefa, ela vem para o primeiro plano e
retoma a atividade no topo da pilha.
Se o usurio pressionar a tecla BACK, a atividade atual removida da pilha e
destruda. A atividade anterior na pilha retomada. Quando uma atividade
destruda, o sistema no mantm atividade do Estado.
As atividades podem ser instanciadas vrias vezes, at mesmo de outras tarefas.
Salvando estado de atividade
Como discutido acima, o comportamento padro do sistema preserva o estado de uma
atividade quando est parada. Desta forma, quando os usurios navegam de volta para
uma atividade anterior, sua interface parece do jeito que deixou. No entanto, voc pode,
e deve, de forma proativa manter o estado de suas atividades atravs de mtodos de
retorno, caso a atividade seja destruda e deve ser recriada.
Quando o sistema pra uma de suas atividades (como quando inicia uma nova atividade
ou movimenta as tarefas para o fundo), o sistema poderia destruir completamente essa
atividade se ele precisa recuperar a memria do sistema. Quando isso acontece, as
ANDROID, uma viso geral Anderson Duarte de Amorim
57
informaes sobre o estado da atividade so perdidas. Se isso acontecer, o sistema ainda
sabe que a atividade tem um lugar na parte de trs da pilha, mas quando a atividade
trazida para o topo da pilha, o sistema deve recri-la (em vez de retom-la). A fim de
evitar a perda do trabalho do usurio, voc deve mant-la de forma proativa atravs da
aplicao do mtodo onSaveInstanceState() de retorno de sua atividade.
Gerenciando tarefas
A forma como o Android gerencia as tarefas e a pilha de volta, como descrito acima -
colocando todas as atividades que comearam sucessivamente na mesma tarefa e em
uma pilha "last in, first out" - funciona muito bem para a maioria das aplicaes e voc
no deve se preocupar em como suas atividades esto associadas a tarefas ou como eles
existem na parte de trs da pilha. No entanto, voc pode decidir que voc deseja
interromper o comportamento normal. Talvez voc queira uma atividade em seu
aplicativo para iniciar uma nova tarefa quando iniciada (em vez de ser colocada dentro
da tarefa atual), ou, quando voc comea uma atividade, que pretende apresentar uma
instncia existente da mesma (em vez de criar uma nova instncia no topo da pilha de
volta), ou, voc quer a sua pilha para ser limpas de todas as activitiesstart, com exceo
para a atividade de raiz quando o usurio deixa a tarefa.
Voc pode fazer essas coisas e mais, com atributos no manifesto da <activity> e com
bandeiras de inteno que voc passa para startActivity().
Neste sentido, os principais atributos de <activity> que voc pode usar so:
taskAffinity
launchMode
allowTaskReparenting
clearTaskOnLaunch
alwaysRetainTaskState
finishOnTaskLaunch
E as principais bandeiras de inteno voc pode usar so:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_SINGLE_TOP
ANDROID, uma viso geral Anderson Duarte de Amorim
58
Ateno: A maioria dos aplicativos no deve interromper o comportamento padro de
atividades e tarefas. Se voc determinar que seja necessrio para a sua atividade
modificar o comportamento padro, tenha cuidado e no se esquea de testar a
usabilidade da atividade durante o lanamento e quando se navega de volta a ele de
outras atividades e tarefas com a tecla BACK. Certifique-se de teste para os
comportamentos de navegao que possam ser incompatveis com o comportamento
esperado do usurio.
Definio de modos de lanamento
Modos de Lanamento permitem que a definir como uma nova instncia de uma
atividade est associada tarefa atual. Voc pode definir diferentes modos de
lanamento de duas maneiras:
Usando o arquivo de manifesto
o Quando voc declarar uma atividade em seu arquivo de manifesto, voc
pode especificar como a atividade deve se associar com as tarefas
quando iniciada.
Usando as opes de Intenes
o Quando voc chamar startActivity(), voc pode incluir uma bandeira na
Intent que declara como (ou se) a nova atividade deve associar com a
tarefa atual.
Como tal, se a atividade A inicia a atividade B, a atividade B pode definir no seu
manifesto de como ele deve se associar com a tarefa atual (caso exista) e uma atividade
tambm pode pedir o quanto a atividade B deve associar com a tarefa atual. Se ambas as
atividades definem como a atividade B deve associar com uma tarefa, ento a
solicitao da atividade A (como definido na inteno) honrada sobre o pedido da
atividade B (como definido no seu manifesto).
Nota: Alguns dos modos disponveis no lanamento do manifesto no esto disponveis
como sinalizadores para uma inteno e, tambm, alguns modos de lanamento
disponvel como sinalizadores para a inteno pode no ser definida no manifesto.

ANDROID, uma viso geral Anderson Duarte de Amorim
59
Usando o arquivo de manifesto
Quando declarar uma atividade em seu arquivo de manifesto, voc pode especificar
como a atividade deve associar com uma tarefa usando o atributo launchMode do
elemento <activity>.
O atributo launchMode especifica uma instruo sobre como a atividade deve ser
lanada em uma tarefa. H quatro modos diferentes de lanamento voc pode atribuir ao
atributo launchMode:
"standard" (o modo padro)
Padro. O sistema cria uma nova instncia da atividade na tarefa de que foi
iniciado e mapeia a inteno a ele. A atividade pode ser instanciada vrias
vezes, cada instncia pode pertencer a diferentes tarefas e uma tarefa pode ter
mltiplas instncias.
"singleTop"
Se uma instncia da atividade j existe no topo da tarefa atual, o sistema mapeia
da estncia atravs de uma chamada para o seu mtodo onNewIntent(), ao invs
de criar uma nova instncia da atividade. A atividade pode ser instanciada vrias
vezes, cada instncia pode pertencer a diferentes tarefas e uma tarefa pode ter
mltiplas instncias (mas s se a atividade na parte superior da pilha de retorno
no uma instncia existente da atividade).
Por exemplo, suponha que uma tarefa que est na pilha consiste de uma
atividade de raiz A com as atividades B, C e D no topo (a pilha ABCD, D est
no topo). A inteno chega para uma atividade do tipo D. Se D tem o modo de
lanamento padro "standard", uma nova instncia da classe lanada e se torna
a pilha ABCDD. No entanto, se D est no modo de lanamento "singleTop", a
instncia existente do D entregue inteno por meio onNewIntent(), porque
est no topo da pilha, a pilha continua ABCD. No entanto, se a inteno chega
para uma atividade do tipo B, ento, uma nova instncia de B adicionada
pilha, mesmo se o seu modo de lanamento "singleTop".
Nota: Quando uma nova instncia de uma atividade criada, o usurio pode
pressionar a tecla Back para retornar atividade anterior. Mas quando uma
ANDROID, uma viso geral Anderson Duarte de Amorim
60
instncia existente de uma atividade lida com uma nova inteno, o usurio no
poder pressionar a tecla Voltar para retornar ao estado da atividade antes da
nova inteno chegaram a onNewIntent().
"singleTask"
O sistema cria uma nova tarefa e instancia a atividade na raiz da nova tarefa. No
entanto, se uma instncia da atividade j existe em uma tarefa separada, o
sistema mapeia a inteno da instncia existente atravs de um convite sua
onNewIntent(), ao invs de criar uma nova instncia. Apenas uma instncia da
atividade pode existir ao mesmo tempo.
Nota: Embora a atividade comee em uma nova tarefa, a tecla BACK ainda
retorna o usurio para a atividade anterior.
"singleInstance" .
O mesmo que "singleTask", exceto que o sistema no inicia qualquer outra
atividade para a tarefa, segurando a instncia. A atividade sempre e nico
membro dessa tarefa; quaisquer atividades iniciadas por este abrem um em uma
tarefa separada.
Como outro exemplo, o navegador Android declara que a atividade do navegador web
deve sempre aberta em sua prpria tarefa, especificando o modo de lanamento
singleTask no elemento <activity>. Isto significa que, se o aplicativo emite a inteno
de abrir o navegador do Android, a sua atividade no colocada na mesma tarefa que a
sua aplicao. Em vez disso, ou uma nova tarefa para o navegador iniciada ou, se o
navegador j tem uma tarefa em execuo em segundo plano, essa tarefa antecipada
para lidar com a nova inteno.
Independentemente de uma atividade ser iniciada em uma nova tarefa ou na mesma
tarefa como a atividade que comeou, a tecla BACK sempre leva o usurio para a
atividade anterior. Entretanto, se voc iniciar uma atividade de sua tarefa (Tarefa A),
que especifica o modo de lanamento sendo singleTask, ento a atividade pode ter uma
instancia em background que pertence a uma tarefa com a sua prpria pilha de volta
(Tarefa B). Neste caso, quando a tarefa B antecipada para lidar com uma nova
ANDROID, uma viso geral Anderson Duarte de Amorim
61
inteno, a tecla BACK navega de volta atravs das atividades na tarefa B antes de
retornar atividade do topo da tarefa A. Figura 4 visualiza este tipo de cenrio.

Figura 4. A representao de como uma atividade com o modo de lanar "singleTask" adicionada
pilha de volta. Se a atividade j faz parte de uma tarefa em segundo plano com a sua prpria pilha de
volta (Tarefa B), ento toda a volta da pilha tambm vem para a frente, em cima da tarefa atual (Tarefa
A).
Nota: O comportamento que voc especificar para a sua atividade com a launchMode
pode ser anulado por bandeiras includas com a inteno de iniciar a sua atividade,
como discutido na prxima seo.
Usando as opes de intenes
Ao iniciar uma atividade, voc pode modificar o padro de associao de uma atividade,
incluindo na inteno que voc entrega a startActivity(). As bandeiras que podem ser
usadas para modificar o comportamento padro so:
FLAG_ACTIVITY_NEW_TASK
Iniciar a atividade em uma nova tarefa. Se a tarefa j est em execuo para a
atividade que voc est comeando agora, essa tarefa levada para o primeiro
plano com o seu ltimo estado restaurado e a atividade recebe a nova inteno
em onNewIntent().
ANDROID, uma viso geral Anderson Duarte de Amorim
62
Isso produz o mesmo comportamento que a "singleTask", discutido na seo
anterior.
FLAG_ACTIVITY_SINGLE_TOP
Se a atividade que est sendo iniciado a atividade atual (no topo da pilha de
volta), ento a instncia existente recebe uma chamada para onNewIntent(), em
vez de criar uma nova instncia da atividade.
Isso produz o mesmo comportamento que a "singleTop", discutido na seo
anterior.
FLAG_ACTIVITY_CLEAR_TOP
Se a atividade a ser iniciada j est em execuo na tarefa atual, ento ao invs
de lanar uma nova instncia da atividade, todas as outras atividades em cima
dela so destrudas e essa inteno entregue instncia retomada da atividade
(agora no topo, atravs onNewIntent()).
No h nenhum valor para o launchMode que produz esse comportamento.
FLAG_ACTIVITY_CLEAR_TOP mais freqentemente utilizado em conjunto
com FLAG_ACTIVITY_NEW_TASK. Quando usados em conjunto, essas
bandeiras so uma maneira de localizar uma atividade existente em outra tarefa e
coloc-la em uma posio onde ela pode responder inteno.
Nota: Se o modo de lanamento da atividade designada "standard", ela
tambm removida da pilha e uma nova instncia lanada em seu lugar para
lidar com o intuito de entrada. Isso porque uma nova instncia sempre criada
para uma nova inteno, quando a modalidade de lanamento "standard.
Manipulao de afinidades
A afinidade indica a qual tarefa uma atividade prefere pertencer. Por padro, todas as
atividades da mesma aplicao tm afinidade entre si. Ento, por padro, todas as
atividades no mesmo aplicativo preferem estar na mesma tarefa. No entanto, voc pode
modificar o padro de afinidade para uma atividade. Atividades definidas em diferentes
aplicaes podem compartilhar uma afinidade, ou atividades definidas no mesmo
aplicativo podem ter diferentes afinidades de tarefas.
ANDROID, uma viso geral Anderson Duarte de Amorim
63
Voc pode modificar a afinidade de uma atividade especfica com o atributo
taskAffinity do <activity> elemento.
O atributo taskAffinity tem um valor de seqncia, que deve ser exclusivo do nome do
pacote padro declarada no elemento <manifest>, porque o sistema usa esse nome para
identificar a afinidade de tarefas padro para o aplicativo.
A afinidade entra em jogo em duas circunstncias:
Quando a inteno que inicia uma atividade contm
FLAG_ACTIVITY_NEW_TASK.
o Uma nova atividade , por padro, lanada na tarefa da atividade que
chamou startActivity(). empurrada para o topo da pilha do chamador. No
entanto, se a inteno passada para startActivity() contm o
FLAG_ACTIVITY_NEW_TASK, o sistema procura por uma tarefa
diferente para abrigar a nova atividade. Muitas vezes, uma nova tarefa. No
entanto, ele no tem que ser. Se j existe uma tarefa, com a mesma afinidade
que a nova atividade, a atividade lanada nessa tarefa. Se no, ele comea
uma nova tarefa.
o Se este sinalizador faz uma atividade para iniciar uma nova tarefa e que o
usurio pressiona a tecla HOME para deix-lo, deve haver alguma maneira
para o usurio navegar de volta para a tarefa. Algumas entidades (como o
gerente de comunicao) sempre iniciam as atividades em uma tarefa
externa, nunca como parte de si prpria, assim eles sempre colocam
FLAG_ACTIVITY_NEW_TASK nas intenes para passar a startActivity().
Se voc tiver uma atividade que pode ser invocada por uma entidade externa
que possa usar esta bandeira, tome cuidado para que o usurio tenha uma
maneira independente para voltar para a tarefa que comeou como um cone
do lanador (a atividade radicular da tarefa tem uma inteno de filtro
CATEGORY_LAUNCHER).
Quando uma atividade tem seu atributo allowTaskReparenting definido como "true".
Neste caso, a atividade pode se mover da tarefa que comeou para a tarefa que tem
afinidade, quando essa tarefa vem em primeiro plano.
ANDROID, uma viso geral Anderson Duarte de Amorim
64
Por exemplo, suponha que uma atividade que relata as condies meteorolgicas em
cidades selecionadas definida como parte de um aplicativo de viagens. Ele tem a
mesma afinidade como outras atividades na mesma aplicao (a afinidade aplicativo
padro) e permite que re-parentalidade com esse atributo. Quando uma de suas
atividades inicia a atividade de reportar o tempo, inicialmente pertencente mesma
tarefa que a sua atividade. No entanto, quando a tarefa da aplicao de viagens volta
ao primeiro plano, a atividade de reportar oo tempo designada para essa tarefa e
exibida dentro dela.
Dica: Se um arquivo .apk contiver mais de uma "aplicao" do usurio, voc
provavelmente vai querer usar o atributo taskAffinity para atribuir diferentes
afinidades para as atividades associadas a cada "pedido".
Limpando a pilha de volta
Se o usurio deixar uma tarefa por um longo tempo, o sistema cancela a tarefa de todas
as atividades exceto a atividade de raiz. Quando o usurio retorna para a tarefa
novamente, somente a atividade da raiz restaurada. O sistema se comporta desta
maneira, porque, depois de um longo perodo de tempo, os usurios provavelmente
abandonaram o que faziam antes e esto retornando para a tarefa para comear algo
novo.
H alguns atributos de atividade que voc pode usar para modificar esse
comportamento:
alwaysRetainTaskState
Se este atributo definido como "true" na atividade de raiz de uma tarefa, o
comportamento padro que acabamos de descrever no acontece. A tarefa retm todas
as atividades na sua pilha, mesmo aps um longo perodo.
clearTaskOnLaunch
Se este atributo definido como "true" na atividade de raiz de uma tarefa, a pilha
limpa at a atividade de raiz sempre que o usurio deixa a tarefa e retorna a ela. Em
outras palavras, o oposto do alwaysRetainTaskState. O usurio sempre retorna para a
tarefa em seu estado inicial, mesmo aps estar deixando a tarefa por apenas um
momento.
ANDROID, uma viso geral Anderson Duarte de Amorim
65
finishOnTaskLaunch
Esse atributo como clearTaskOnLaunch, mas opera em uma nica atividade, no em
uma tarefa inteira. Ela tambm pode fazer alguma atividade ir embora, incluindo a
atividade de raiz. Quando definido como "true", a atividade continua a ser parte da
tarefa apenas para a sesso atual. Se o usurio sai e depois volta para a tarefa, ela no
est mais presente.
Iniciando uma tarefa
Voc pode configurar uma atividade como o ponto de entrada para uma tarefa, dando-
lhe um filtro com a inteno "android.intent.action.MAIN" como a ao especificada e
"android.intent.category.LAUNCHER" como a categoria especificada. Por exemplo:
<activity ... >
<intent-filter ... >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
...
</activity>
A inteno do filtro deste tipo faz um cone e uma legenda para a atividade a ser exibida
na tela do menu, dando aos usurios uma maneira de iniciar a atividade e para retornar
para a tarefa que ele cria em qualquer momento depois de ter sido lanado.
Esta segunda habilidade importante: o usurio deve ser capaz de deixar uma tarefa e,
em seguida, voltar a ela mais tarde com o lanador de atividade. Por esta razo, os dois
modos de iniciar as atividades que marcam o incio, como sempre, uma tarefa,
"singleTask" e " "singleInstance" , devem ser usados somente quando a atividade tem
um filtro ACTION_MAIN e CATEGORY_LAUNCHER. Imagine, por exemplo, o que
poderia acontecer se o filtro estiver faltando: Uma inteno lana uma atividade
"singleTask", iniciando uma nova tarefa, e o usurio passa algum tempo a trabalhar
nessa tarefa. O usurio pressiona o HOME. A tarefa agora enviada para o fundo e fica
invisvel. Porque ele no representado na tela do aplicativo, o usurio no tem como
voltar para a tarefa.
Para os casos onde voc no deseja que o usurio seja capaz de retornar a uma
atividade, defina o elemento de <activity>, finishOnTaskLaunch, para "true".

ANDROID, uma viso geral Anderson Duarte de Amorim
66
Servios
Um Service um componente da aplicao que pode executar operaes de longa
durao em segundo plano e no oferece uma interface de usurio. Outro componente
do aplicativo pode iniciar um servio e vai continuar a rodar em segundo plano, mesmo
se o usurio muda para outro aplicativo. Alm disso, um componente pode se ligar a um
servio para interagir com ele e at mesmo realizar a comunicao entre processos
(IPC). Por exemplo, um servio pode lidar com as transaes de rede, tocar msica,
executar I/O, ou interagir com um provedor de contedo, todos no fundo.
Um servio pode essencialmente de duas formas:
Iniciado
Um servio "iniciado" quando um componente da aplicao (como uma
atividade) inicia-o chamando startService(). Uma vez iniciado, o servio pode
ser executado em segundo plano por tempo indeterminado, mesmo se o
componente que o comeou destrudo. Normalmente, um servio iniciado
executa uma nica operao e no retorna um resultado para o chamador. Por
exemplo, pode fazer o download ou upload de um arquivo pela rede. Quando a
operao feita, o servio deve parar.
Ligado
Um servio "ligado" quando um componente da aplicao liga-se a ele
chamando bindService(). Um servio vinculado oferece uma interface cliente-
servidor que permite que os componentes interajam com o servio, enviar
pedidos, obter resultados, e at mesmo faz-lo atravs de processos de
comunicao entre processos (IPC). Um servio vinculado s executado
enquanto outro componente de aplicao est vinculado a ele. Vrios
componentes podem ligar para o servio de uma s vez, mas quando todos eles
se desvinculam, o servio destrudo.
Embora essa documentao geralmente aborda esses dois tipos de servios
separadamente, o servio pode funcionar nos dois sentidos, ele pode ser iniciado (para
rodar indefinidamente) e tambm permitir a ligao. simplesmente uma questo de
ANDROID, uma viso geral Anderson Duarte de Amorim
67
saber se voc implementa a dupla de mtodos: onStartCommand() para permitir ao os
componentes inici-lo e onBind() para permitir a ligao.
Independentemente de sua aplicao ser iniciada, ligada, ou ambos, qualquer
componente de aplicativo pode usar o servio (mesmo a partir de um aplicativo
separado), da mesma forma que qualquer componente pode usar uma atividade
iniciando-a com uma Intent. No entanto, voc pode declarar o servio como privado, no
arquivo de manifesto, e bloquear o acesso de outros aplicativos.
Ateno: O servio executado no segmento principal de sua hospedagem, o servio
de processo no cria seu prprio segmento e no executado em um processo
separado (a menos que voc especifique o contrrio). Isso significa que, se o servio
vai fazer todo o trabalho intensivo da CPU ou o bloqueio de operaes (como a
reproduo de MP3 ou de rede), voc deve criar um novo segmento dentro do servio
para fazer esse trabalho. Ao utilizar uma thread separada, voc vai reduzir o risco de
erros como aplicao no responde (ANR) e o thread principal do aplicativo pode
permanecer dedicado interao do usurio com suas atividades.
O bsico
Voc deve utilizar um servio ou um thread?
O servio simplesmente um componente que pode ser
executado em segundo plano, mesmo quando o usurio no est
interagindo com o aplicativo. Assim, voc deve criar um servio
s para o que voc precisa.
Se voc precisa realizar o trabalho fora de sua linha principal,
mas apenas enquanto o usurio est interagindo com o aplicativo,
ento voc deve, provavelmente, criar uma nova thread e no um
servio. Por exemplo, se voc quiser tocar algumas msicas, mas
apenas quando sua atividade est em execuo, voc pode criar
uma lista de discusso em onCreate(), comear a utilizar em
onStart() , e depois parar em onStop(). Tambm considere usar
AsyncTask ou HandlerThread, em vez da tradicional classe
Thread.
Lembre-se que se voc usar um servio, ele ainda executado no
ANDROID, uma viso geral Anderson Duarte de Amorim
68
Para criar um servio,
voc deve criar uma
subclasse de Service (ou
uma de suas subclasses existentes). Em sua execuo, necessrio substituir alguns
mtodos de callback para lidar com aspectos essenciais do ciclo de vida do servio e
fornecer um mecanismo de componentes para ligar para o servio, se for o caso. Os
mtodos mais importantes de retorno so:
onStartCommand()
O sistema chama este mtodo quando outro componente, como uma atividade,
solicita que o servio seja iniciado, chamando startService(). Uma vez que este
mtodo executado, o servio iniciado e pode rodar em segundo plano por
tempo indeterminado. Se voc implementar essa, sua a responsabilidade parar
o servio quando seu trabalho feito, chamando stopSelf() ou stopService(). (Se
voc apenas quiser fornecer ligao, voc no precisa aplicar esse mtodo.)
onBind()
O sistema chama este mtodo quando um outro componente quer se vincular
com o servio (por exemplo, executar RPC), chamando bindService(). Na
implementao deste mtodo, voc deve fornecer uma interface que os clientes
usam para se comunicar com o servio, retornando um IBinder. Voc sempre
deve implementar este mtodo, mas se voc no quer permitir a ligao, ento
voc deve retornar null.
onCreate()
O sistema chama este mtodo quando o servio criado, para executar os
procedimentos de configurao (antes de chamar qualquer onStartCommand()
ou onBind()). Se o servio j est em execuo, este mtodo no chamado.
onDestroy()
O sistema chama este mtodo quando o servio no mais usado e est sendo
destrudo. Seu servio deve implementar isso para limpar quaisquer recursos,
tais como threads, ouvintes registrados, receptores, etc. Esta a ltima chamada
que o servio recebe.
thread principal do aplicativo por padro, ento voc deve ainda
criar um novo segmento dentro do servio se executa operaes
intensivas ou bloqueio.
ANDROID, uma viso geral Anderson Duarte de Amorim
69
Se um componente inicia o servio chamando startService() (o que resulta em uma
chamada para onStartCommand()), o servio continua funcionando at que ele pare com
stopSelf() ou outro componente deixa-o chamando stopService().
Se um componente chama bindService() para criar o servio (e onStartCommand() no
chamado), o servio funciona somente enquanto o componente est ligado a ele.
Depois que o servio desvinculado de todos os clientes, o sistema se destri.
O sistema Android fora a parada de um servio somente quando estiver com pouca
memria e deve recuperar os recursos do sistema para a atividade que tem o foco do
usurio. Se o servio est vinculado a uma atividade que tem o foco do usurio, ento
menos provvel de ser morto, e se o servio declarado a ser executado no primeiro
plano (discutido mais tarde), ento ele quase nunca vai ser morto. Caso contrrio, se o
servio foi iniciado e est rodando h muito tempo, ento o sistema ir baixar a sua
posio na lista de tarefas em segundo plano ao longo do tempo e o servio se tornar
altamente suscetvel a matar-se - se o servio iniciado, ento voc deve projet-lo
elegantemente para lanar reincio pelo sistema. Se o sistema mata o seu servio, ele
reinicia logo que os recursos se tornam novamente disponveis (embora isso tambm
dependa do valor que voc retornar do onStartCommand(), como ser discutido mais
tarde).
Declarando um servio no manifesto
Como atividades (e outros componentes), voc deve declarar todos os servios do
arquivo de manifesto do aplicativo.
Para declarar seu servio, adicione um elemento <service> como um filho do elemento
<application>. Por exemplo:
<manifest ... >
...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>
Existem outros atributos que voc pode incluir no <service> para definir propriedades,
como as permisses necessrias para iniciar o servio e o processo em que o servio
deve ser executado.
ANDROID, uma viso geral Anderson Duarte de Amorim
70
Assim como uma atividade, um servio pode definir filtros que permitem a inteno de
outros componentes para invocar o servio utilizando as intenes implcitas. Ao
declarar a inteno de filtros, componentes de qualquer aplicativo instalados no
aparelho do usurio podem, potencialmente, iniciar o seu servio se o servio de
declarar a inteno de filtro que corresponde inteno outro aplicativo passa a
startService() .
Se voc planeja usar o seu servio apenas localmente (as outras aplicaes no o usam),
ento voc no precisa (e no deve) prestar quaisquer filtros de inteno. Sem qualquer
inteno de filtros, voc deve iniciar o servio usando uma inteno explcita dos nomes
de classe do servio.
Alm disso, voc pode garantir que seu servio seja privado, basta somente voc incluir
o atributo android:exported e defini-lo como "false". eficaz mesmo se o servio
fornece filtros de inteno.
Criando um servio iniciado
Um servio iniciado um de outro
componente que se inicia chamando
startService(), resultando em uma chamada
para o mtodo onStartCommand() do servio.
Quando um servio iniciado, ele tem um
ciclo de vida que independente do
componente que comeou e o servio pode
funcionar em segundo plano por tempo
indeterminado, mesmo se o componente que
o comeou destrudo. Como tal, o servio
deve parar quando seu trabalho feito
chamando stopSelf(), ou outro componente
pode par-lo, chamando stopService().
Um componente de aplicao, como uma atividade, pode iniciar o servio chamando
startService() e passando uma Intent que especifica o servio e inclui todos os dados
para o servio deve usar. O servio recebe essa Intent no mtodo onStartCommand().
Segmentao Android 1.6 ou inferior
Se voc estiver construindo uma
aplicao para o Android 1.6 ou
inferior, voc precisa implementar
onStart(), em vez de
onStartCommand() (no Android 2.0,
onStart() foi depreciado em favor do
onStartCommand()).
Para obter mais informaes sobre a
prestao de compatibilidade com
verses do Android superiores a 2.0,
consulte a documentao de
onStartCommand().
ANDROID, uma viso geral Anderson Duarte de Amorim
71
Por exemplo, suponha que uma atividade precisa salvar alguns dados para um banco de
dados on-line. A atividade pode iniciar um servio e entreg-lo para guardar os dados,
passando a inteno de startService(). O servio recebe a inteno em
onStartCommand(), se conecta Internet e executa a operao de banco de dados.
Quando a transao estiver concluda, o servio o pra e ele destrudo.
Ateno: Um servio executa no mesmo processo do aplicativo no qual ele declarado
e na thread principal da aplicao, por padro. Assim, se o servio realiza intensivo ou
o bloqueio de operaes, enquanto o usurio interage com uma atividade a partir do
mesmo aplicativo, o servio vai abrandar o desempenho da atividade. Para evitar
afetar o desempenho do aplicativo, voc deve iniciar uma nova thread dentro do
servio.
Tradicionalmente, h duas classes que voc pode estender para criar um servio
iniciado:
Service
Esta a classe base para todos os servios. Quando voc estender essa classe,
importante que voc crie um novo segmento para fazer todo o trabalho, pois o
servio usa a linha principal do aplicativo, por padro, o que poderia diminuir o
desempenho de qualquer atividade de sua aplicao que est rodando.
IntentService
Esta uma subclasse de Service que utiliza um thread de trabalho para lidar com
todos os pedidos de incio, um de cada vez. Esta a melhor opo se voc no
exigir que o servio de lidar com vrias solicitaes em simultneo. Tudo que
voc precisa fazer implementar onHandleIntent(), que recebe a inteno de
cada solicitao de incio para que voc possa fazer o trabalho de fundo.
Estendendo a classe IntentService
Porque a maioria dos servios iniciados no precisam lidar com mltiplas solicitaes
ao mesmo tempo (que pode realmente ser um cenrio perigoso de multi-threading),
melhor se voc implementar o seu servio usando o IntentService.
O IntentService faz o seguinte:
ANDROID, uma viso geral Anderson Duarte de Amorim
72
Cria um thread de trabalho padro que executa todas as intenes entregues ao
onStartCommand() em separado do thread principal de sua aplicao.
Cria uma fila de trabalho que passa uma inteno de cada vez para seu
onHandleIntent() de execuo, para que no tenha que se preocupar com multi-
threading.
Interrompe o servio, aps todos os pedidos de incio ter sido manipulados,
ento voc nunca tem que chamar stopSelf().
Fornece implementao padro de onBind() que retorna nulo.
Fornece uma implementao padro de onStartCommand() que envia a inteno
da fila de trabalho e, em seguida, onHandleIntent() de execuo.
Tudo isto se acrescenta ao fato de que tudo que voc precisa fazer implementar
onHandleIntent() para fazer o trabalho fornecido pelo cliente. (Embora, voc tambm
precisa fornecer um construtor pequeno para o servio).
Aqui est um exemplo de implementao de IntentService :
public class HelloIntentService extends IntentService {

/**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}

/**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
ANDROID, uma viso geral Anderson Duarte de Amorim
73
}
}
}
}
Isso tudo que voc precisa: um construtor e uma implementao de onHandleIntent().
Se voc decidir tambm substituir os mtodos de retorno de chamada, tais como
onCreate(), onStartCommand(), ou onDestroy(), no se esquea de chamar a
implementao de super, de modo que o IntentService possa lidar corretamente com a
vida do thread.
Por exemplo, onStartCommand() deve retornar a implementao padro (que como a
inteno entregue a onHandleIntent()):
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
Alm do onHandleIntent(), o nico mtodo a partir do qual voc no precisa chamar o
super classe onBind() (mas voc s precisa implementar caso o servio permita a
ligao).
Estendendo a classe de servio
Como voc viu na seo anterior, utilizar IntentService faz sua implementao de um
servio iniciado muito simples. Se, no entanto, necessrio o seu servio executar
multi-threading (em vez de processar pedidos atravs da fila de trabalho), ento voc
pode estender a classe Service para lidar com cada inteno.
Para efeito de comparao, o cdigo de exemplo a seguir uma implementao do
Service que executa o mesmo trabalho exatamente como o exemplo acima usando
IntentService. Ou seja, para cada solicitao, ele usa um thread para executar o trabalho
e os processos de um nico pedido por vez.
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;

// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
ANDROID, uma viso geral Anderson Duarte de Amorim
74
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}

@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();

// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);

// If we get killed, after returning from here, restart
return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
ANDROID, uma viso geral Anderson Duarte de Amorim
75

@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}


ANDROID, uma viso geral Anderson Duarte de Amorim
76
Como voc pode ver, d muito mais trabalho do que usar um IntentService.
No entanto, como voc lida com cada chamada para onStartCommand() por si s, voc
pode executar vrias solicitaes em simultneo. Isso no o que este exemplo faz, mas
se isso que voc quer ento voc pode criar um novo tpico para cada pedido e
execut-los imediatamente (em vez de aguardar a solicitao anterior para terminar).
Observe que o mtodo onStartCommand() deve retornar um inteiro. O inteiro um
valor que descreve como o sistema deve continuar o servio a partir do evento em que o
sistema o mata (como discutido acima, a implementao padro para IntentService trata
isso para voc, mas voc capaz de modific-lo). O valor de retorno de
onStartCommand() deve ser uma das seguintes constantes:
START_NOT_STICKY
Se o sistema mata o servio aps onStartCommand() retornar, no recria o
servio, salvo se houver pendncia de intenes para entregar. Esta a opo
mais segura para evitar a execuo de seu servio quando no for necessrio e
quando a sua aplicao pode simplesmente reiniciar os trabalhos inacabados.
START_STICKY
Se o sistema mata o servio aps onStartCommand() retornar, recria o servio e
chamar onStartCommand(), mas no entrega novamente a ltima inteno. Em
vez disso, o sistema chama onStartCommand() com uma inteno nula, a menos
que houver pendncia de intenes para iniciar o servio, nesse caso, os
propsitos so entregues. Isso adequado para media players (ou afins) que no
esto executando comandos, mas rodam indefinidamente espera de uma
interao.
START_REDELIVER_INTENT
Se o sistema mata o servio aps onStartCommand() retornar, recria o servio e
chama onStartCommand() com a ltima inteno que foi entregue para o
servio. Quaisquer intenes pendentes so entregues em troca. Isso adequado
para os servios que esto ativamente realizando um trabalho que deve ser
imediatamente reiniciado, como baixar um arquivo.
ANDROID, uma viso geral Anderson Duarte de Amorim
77
Iniciando um servio
Voc pode iniciar um servio de uma atividade ou componente de outro aplicativo por
meio de um Intent (especificando o servio para iniciar) para startService(). O sistema
Android chama o mtodo onStartCommand() do servio do e passa a Intent. (Voc
nunca deve chamar onStartCommand() diretamente.)
Por exemplo, uma atividade pode iniciar o servio de exemplo na seo anterior
(HelloSevice) com a inteno explcita com startService():
Intent intent = new Intent(this, HelloService.class);
startService(intent);
O startService() retorna imediatamente e o sistema Android chama o mtodo
onStartCommand() do servio. Se o servio no estiver sendo executado, o sistema
chama primeiro onCreate(), em seguida, chama onStartCommand().
Se o servio no prov ligao, a inteno entregue com startService() o nico modo
de comunicao entre o componente de aplicao e o servio. No entanto, se voc
quiser o servio para enviar um resultado de volta, o cliente que inicia o servio pode
criar uma PendingIntent para uma transmisso (com getBroadcast()) e entreg-lo ao
servio da Intent que inicia o servio. O servio pode ento usar a transmisso para
fornecer um resultado.
Vrios pedidos para iniciar o resultado do servio em vrias correspondncias chamam
o onStartCommand() do servio. No entanto, apenas um pedido para parar o servio
(com stopSelf() ou stopService()) necessrio.
Parando um servio
O servio iniciado deve gerenciar seu prprio ciclo de vida. Ou seja, o sistema no para
ou destri o servio a menos que ele deva recuperar a memria do sistema e o servio
continua a funcionar aps onStartCommand() retornar. Assim, o servio deve parar,
chamando stopSelf() ou outro componente pode par-lo, chamando stopService().
Uma vez solicitado a parar com stopSelf() ou stopService(), o sistema destri o servio
o mais rapidamente possvel.
No entanto, se o servio trabalha com pedidos mltiplos para onStartCommand() ao
mesmo tempo, ento voc no deve interromper o servio quando tiver terminado o
ANDROID, uma viso geral Anderson Duarte de Amorim
78
processamento de um pedido inicial, porque voc pode ter uma vez recebido um pedido
novo comeo (parando no final do primeiro pedido iria encerrar a segunda). Para evitar
esse problema, voc pode usar stopSelf(int) para garantir que o seu pedido para parar o
servio sempre baseado no incio pedido mais recente. Ou seja, quando voc chamar
stopSelf(int), voc passa o ID do pedido inicial (o startId entregue para
onStartCommand()) ao qual o pedido de parada corresponde. Ento, se o servio
recebeu um pedido antes de voc fosse capaz de chamar stopSelf(int) , o ID no
corresponder e o servio no vai parar.
Ateno: importante que o aplicativo pare seus servios quando o trabalho est
pronto, para evitar o desperdcio de recursos do sistema e consumo de bateria. Se
necessrio, outros componentes podem interromper o servio pela chamada de
stopService(). Mesmo se voc permitir chamada ao servio, voc deve sempre parar o
servio a si mesmo se ele j recebeu uma chamada para onStartCommand().
Criando um servio vinculado
Um servio vinculado aquele que permite que os componentes do aplicativo se
vinculem a ele chamando bindService() para criar uma ligao de longa data (e
geralmente no permitem aos componentes inici-lo, chamando startService()).
Voc deve criar um servio ligado quando voc quiser interagir com o servio de
atividades e outros componentes em seu aplicativo ou para expor algumas das
funcionalidades do aplicativo para outros aplicativos, atravs da comunicao entre
processos (IPC).
Para criar um servio vinculado, voc deve implementar o mtodo onBind()para
retornar um IBinder que define a interface de comunicao com o servio. Outros
componentes do aplicativo pode ento chamar bindService() para recuperar a interface e
comear a chamar os mtodos do servio. O servio s vive para servir o componente
de aplicao que ligado a ele, ento quando no h componentes vinculados ao
servio, o sistema o destri (voc no precisa parar um servio ligado no jeito que voc
tem quando o servio iniciado atravs onStartCommand()).
Para criar um servio vinculado, a primeira coisa que voc deve fazer definir a
interface que especifica como um cliente pode se comunicar com o servio. Essa
interface entre o servio e o cliente deve ser uma implementao de IBinder e o que o
ANDROID, uma viso geral Anderson Duarte de Amorim
79
seu servio deve retornar a partir do mtodo de retorno onBind(). Uma vez que o cliente
recebe a IBinder , pode comear a interagir com o servio por meio dessa interface.
Vrios clientes podem se ligar ao servio de uma s vez. Quando um cliente concluiu a
interao com o servio, ele chama unbindService() para se desvincular. Uma vez que
no h clientes vinculados ao servio, o sistema destri o servio.
Enviando notificaes para o usurio
Uma vez em execuo, um servio pode notificar o usurio de eventos usando
notificaes toast ou notificaes da barra de status.
Uma notificao toast uma mensagem que aparece na superfcie da janela atual por
um momento e depois desaparece, enquanto uma notificao de barra de status fornece
um cone na barra de status com uma mensagem, que o usurio pode selecionar a fim de
tomar uma ao (como iniciar uma atividade).
Normalmente, uma notificao de barra de status a melhor tcnica quando algum
trabalho de fundo tenha sido concludo (como um download do arquivo completo) e
agora o usurio pode agir sobre ela. Quando o usurio seleciona a notificao a partir da
viso expandida, a notificao pode iniciar uma atividade (tal como para visualizar o
arquivo baixado).
Executando um servio em primeiro plano
Um servio de primeiro plano um servio que considerado como sendo algo que o
usurio esteja atento e, portanto, no um candidato para o sistema matar quando com
pouca memria. Um servio de primeiro plano deve prever uma notificao na barra de
status, que colocado abaixo da posio "em curso", o que significa que a notificao
no pode ser dispensada a menos que o servio ou est parado ou foi removido do
primeiro plano.
Por exemplo, um leitor de msica que toca a partir de um servio, deve ser definido para
ser executado em primeiro plano, porque o usurio est explicitamente consciente do
seu funcionamento. A notificao na barra de status pode indicar a msica atual e
permitir que o usurio inicie uma atividade para interagir com o leitor de msica.
ANDROID, uma viso geral Anderson Duarte de Amorim
80
Para solicitar que o servio seja executado em primeiro plano, chame startForeground().
Este mtodo tem dois parmetros: um nmero inteiro que identifica a notificao e a
notificao na barra de status. Por exemplo:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION, notification);
Para remover o servio do primeiro plano, chama-se stopForeground(). Este mtodo tem
um valor booleano, indicando se deseja remover a notificao de barra de status
tambm. Este mtodo no para o servio. No entanto, se voc parar o servio enquanto
ele ainda est executando em primeiro plano a notificao tambm removida.
Nota: Os mtodos startForeground() e stopForeground() foram introduzidos no
Android 2.0 (API Nvel 5).
Gerenciando ciclo de vida de um servio
O ciclo de vida de um servio muito mais simples do que o de uma atividade. No
entanto, ainda mais importante que voc preste ateno forma como o servio
criado e destrudo, porque um servio pode ser executado em segundo plano, sem que o
utilizador perceba.
O ciclo de vida do servio desde quando ele criado at quando ele destrudo - pode
seguir dois caminhos diferentes:
O servio comeou
O servio criado quando um outro componente chama startService(). O servio
executado indefinidamente e, em seguida, deve ser parado chamando stopSelf().
Outro componente tambm pode interromper o servio pela chamada de
stopService(). Quando o servio for interrompido, o sistema o destri.
Um servio vinculado
O servio criado quando um outro componente (um cliente) chama bindService().
O cliente se comunica com o servio atravs de uma interface IBinder. O cliente
ANDROID, uma viso geral Anderson Duarte de Amorim
81
pode fechar a conexo chamando unbindService(). Vrios clientes podem chamar o
mesmo servio e quando todos eles desvincularem-se, o sistema destri o servio.
(O servio no precisa parar si mesmo).
Estes dois caminhos no so totalmente distintos. Ou seja, voc pode chamar um
servio que j foi iniciado com startService(). Por exemplo, um servio de msica de
fundo pode ser iniciado chamando startService() com uma Intent que identifica a msica
a tocar. Mais tarde, possivelmente quando o usurio deseja exercer algum controle sobre
o player ou obter informaes sobre a msica atual, uma atividade pode se ligar ao
servio chamando bindService(). Em casos como este, stopService() ou stopSelf() no
chegam a parar o servio at que todos os clientes se desacoplem.
Aplicando o ciclo de vida dos callbacks
Como uma atividade, um ciclo de vida do servio tem mtodos de retorno que voc
pode implementar para monitorar as mudanas no estado do servio e realizar o trabalho
no momento oportuno. O seguinte esqueleto de servio demonstra todos os mtodos de
ciclo de vida:

Figura 2. O ciclo de vida do servio. O diagrama esquerda mostra o ciclo de vida quando o servio
criado com startService() e o diagrama da direita mostra o ciclo de vida quando o servio criado com
bindService().
ANDROID, uma viso geral Anderson Duarte de Amorim
82
public class ExampleService extends Service {
int mStartMode; // indicates how to behave if the service is killed
IBinder mBinder; // interface for clients that bind
boolean mAllowRebind; // indicates whether onRebind should be used

@Override
public void onCreate() {
// The service is being created
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The service is starting, due to a call to startService()
return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
// A client is binding to the service with bindService()
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// All clients have unbound with unbindService()
return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
// A client is binding to the service with bindService(),
// after onUnbind() has already been called
}
@Override
public void onDestroy() {
// The service is no longer used and is being destroyed
}
}
Nota: Ao contrrio mtodos de retorno do ciclo de vida da atividade, voc no
obrigado a chamar a implementao da superclasse dos mtodos de callback.
Ao implementar esses mtodos, voc pode controlar dois loops aninhados do ciclo de
vida do servio:
A vida inteira de um servio acontece entre o momento onCreate() ser
chamado e o tempo onDestroy() retornado. Como uma atividade, um servio
tem a sua configurao inicial em onCreate() e libera todos os recursos
remanescentes em onDestroy(). Por exemplo, um servio de reproduo de
msica pode criar o segmento onde a msica ser tocada em onCreate(),
ento para a thread em onDestroy().
ANDROID, uma viso geral Anderson Duarte de Amorim
83
Os mtodos onCreate() e onDestroy() so chamados para todos os servios,
sejam eles criados por startService() ou bindService() .
A vida ativa de um servio comea com uma chamada de um
onStartCommand() ou onBind(). Cada mtodo entrega a Intent que foi passado
tanto startService() quanto bindService(), respectivamente.
Se o servio for iniciado, o tempo de vida ativa termina ao mesmo tempo em que
toda a vida termina (o servio continua ativo mesmo aps onStartCommand()
retornar). Se o servio est vinculado, a vida ativa termina quando onUnbind()
retorna.
Nota: Apesar de um servio iniciado ser interrompido por uma chamada para uma
stopSelf() ou stopService(), no h um retorno para o respectivo servio (no h
onStop() de callback). Ento, a menos que o servio esteja vinculado a um cliente, o
sistema destri quando o servio for interrompido, onDestroy() o retorno recebido
apenas.
A figura 2 ilustra os mtodos tpicos de retorno de um servio. Embora a figura separa
os servios que so criados por startService() daquelas criadas pelos bindService() ,
tenha em mente que qualquer servio, no importa como ele iniciado, pode
potencialmente permitir que os clientes chamem-no. Assim, um servio que foi
inicialmente iniciado com onStartCommand() (por um cliente chamando startService() )
pode ainda receber uma chamada para onBind() (quando um cliente solicita
bindService()).

ANDROID, uma viso geral Anderson Duarte de Amorim
84
Servios vinculados
Um servio vinculado o servidor em uma interface cliente-servidor. O servio permite
que os componentes ligados (como em atividades) vinculem-se ao servio, enviem
pedidos, recebam respostas, e at mesmo realizem a comunicao entre processos (IPC).
Um servio ligado normalmente vive apenas enquanto ela serve a outro componente da
aplicao e no executado em segundo plano por tempo indeterminado.
O bsico
Um servio ligado uma
implementao da classe
Service que permite que
outros aplicativos se liguem e
interajam com ele. Para
fornecer ligao para um
servio, voc deve
implementar o onBind()
mtodo de retorno. Esse
mtodo retorna um objeto
IBinder que define a interface
de programao que os
clientes podem usar para
interagir com o servio.
Um cliente pode se ligar ao
servio chamando
bindService(). Quando isso
acontecer, ele deve fornecer
uma implementao de
ServiceConnection, que
monitora a conexo com o
servio. O mtodo
bindService() retorna
imediatamente sem um valor,
Vinculao a um servio iniciado
Conforme discutido no captulo sobre Servio, voc pode
criar um servio que seja iniciado e vinculado. Ou seja, o
servio pode ser iniciado chamando startService(), que
permite que o servio seja executado indefinidamente, e
tambm permite que um cliente se amarre ao servio
chamando bindService().
Se voc permitir que seu servio seja iniciado e ligado, em
seguida, quando o servio for iniciado, o sistema no
destruir o servio quando todos os clientes desacoplarem.
Em vez disso, voc deve explicitamente parar o servio,
chamando stopSelf() ou stopService().
Embora voc geralmente deva implementar onBind() ou
onStartCommand(), s vezes necessrio aplicar a ambos.
Por exemplo, um tocador de msica pode ser til para
permitir o servio a ser executado indefinidamente e
tambm fornecer vnculo. Desta forma, uma atividade pode
iniciar o servio para jogar alguma msica e a msica
continua a tocar mesmo se o usurio sai do aplicativo.
Ento, quando o usurio retorna para a aplicao, a
atividade pode ligar para o servio para recuperar o
controle da reproduo.
Certifique-se de ler a seo sobre Gerenciamento do ciclo
de vida de um servio vinculado, para obter mais
informaes sobre o ciclo de vida do servio, quando for
feita adio de ligao para um servio iniciado.
ANDROID, uma viso geral Anderson Duarte de Amorim
85
mas quando o sistema Android cria a conexo entre o cliente e o servio, ele chama
onServiceConnected() na ServiceConnection para entregar o IBinder que o cliente pode
usar para se comunicar com o servio.
Vrios clientes podem se conectar ao servio de uma s vez. No entanto, o sistema
chama o mtodo onBind() do servio para recuperar o IBinder somente quando o cliente
liga-se em primeiro lugar. O sistema, em seguida, oferece os mesmos IBinder para
quaisquer clientes que ligam, sem chamar onBind() novamente.
Quando o libera ltimo cliente do servio, o sistema destri o servio (a menos que o
servio tambm foi iniciado por startService() ).
Quando voc implementar o seu servio vinculado, a parte mais importante definir a
interface que o seu mtodo callback onBind() retorna. Existem algumas maneiras
diferentes que voc pode definir o seu servio da interface IBinder e a seo a seguir
discute cada tcnica.
Criando um servio ligado
Ao criar um servio que oferece ligao, voc deve fornecer um IBinder que fornece a
interface de programao que os clientes podem utilizar para interagir com o servio.
Existem trs maneiras com as quais voc pode definir a interface:
Estendendo a classe Binder
Se o servio privado para sua prpria aplicao e executado no mesmo
processo do cliente (o que comum), voc deve criar a sua interface extendendo
o Binder e retornando uma instncia a partir onBind(). O cliente recebe o Binder
e pode us-lo para acessar diretamente os mtodos pblicos disponveis em
qualquer um dos Binder implementados ou at mesmo o Service.
Esta a tcnica preferida quando o servio apenas um trabalhador de fundo
para o seu prprio aplicativo. A nica razo em que voc no deve criar a
interface desta maneira porque o servio utilizado por outras aplicaes ou
atravs de processos separados.

ANDROID, uma viso geral Anderson Duarte de Amorim
86
Usando um Messenger
Se voc precisa de sua interface para trabalhar em processos diferentes, voc
pode criar uma interface para o servio com um Messenger. Desta forma, o
servio define um Handler, que responde a diferentes tipos de mensagem de
objetos. Este Handler a base para um Messenger que podem compartilhar um
IBinder com o cliente, permitindo que o cliente envie comandos para o servio
usando mensagem de objetos. Alm disso, o cliente pode definir um Messenger
prprio para que o servio possa enviar mensagens de volta.
Esta a maneira mais simples para realizar a comunicao entre processos
(IPC), porque o Messenger enfilera todas as solicitaes em um nico segmento
para que voc no tenha que projetar seu servio a ser um thread-safe.
Usando AIDL
AIDL (Android Interface Definition Language) realiza todo o trabalho de
decompor os objetos primitivos em que o sistema operacional possa entender
atravs de processos para executar IPC. A tcnica anterior, usando um
Messenger, realmente baseado em AIDL como a sua estrutura subjacente.
Como mencionado acima, o Messenger cria uma fila de todas as solicitaes do
cliente em um nico segmento, para que o servio receba solicitaes de um de
cada vez. Se, no entanto, voc quiser que o seu servio lide com mltiplas
solicitaes ao mesmo tempo, ento voc pode usar AIDL diretamente. Neste
caso, o servio deve ser capaz de multi-threading e ser construdo thread-safe.
Para usar AIDL diretamente, voc deve criar uma arquivo .aidl que define a
interface de programao. As ferramentas do Android SDK usam esse arquivo
para gerar uma classe abstrata que implementa a interface e lida com o IPC, que
voc pode estender dentro do seu servio.
Nota: A maioria dos aplicativos no devemusar AIDL para criar um servio
ligado, porque ele pode exigir recursos de multithreading e pode resultar em
uma implementao mais complicada. Como tal, AIDL no adequado para a
maioria das aplicaes e este documento no explica como us-lo para seu
servio.
ANDROID, uma viso geral Anderson Duarte de Amorim
87
Estendendo a classe Binder
Se o servio usado somente pela aplicao local e no precisa trabalhar em todos os
processos, ento voc pode implementar seu prprio Binder que fornece o acesso direto
do cliente com os mtodos pblicos no servio.
Nota: Isto s funciona se o cliente e o servio esto no mesmo aplicativo e processo, o
que mais comum. Por exemplo, isso iria funcionar bem para um aplicativo de msica
que tem o efeito de vincular uma atividade a seu prprio servio de msica que est
tocando no fundo.
Veja como configur-lo:
1. Em seu servio, criar uma instncia do Binder que:
o contm mtodos pblicos que o cliente pode chamar
o retorna o atual Service, que tem mtodos pblicos que o cliente pode
chamar
o ou, retorna uma instncia de outra classe hospedada pelo servio com
mtodos pblicos que o cliente pode chamar
2. Retornar essa instncia do Binder do mtodo de retorno onBind().
3. No cliente, receber a Binder do mtodo de retorno onServiceConnected() e
fazer chamadas para o servio vinculado usando os mtodos fornecidos.
Nota: A razo pela qual o servio e o cliente devem estar no mesmo pedido porque o
cliente pode converter o objeto retornado e chamar propriamente de sua API. O servio
e o cliente tambm devem estar no mesmo processo, porque essa tcnica no exerce
qualquer triagem em todos os processos.
Por exemplo, aqui est um servio que oferece aos clientes o acesso a mtodos no
servio por meio de um Binder de execuo:
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();

ANDROID, uma viso geral Anderson Duarte de Amorim
88
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}

/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
O LocalBinder fornece o mtodo getService() de clientes para recuperar a instncia
atual do LocalService. Isso permite aos clientes chamarem mtodos pblicos no servio.
Por exemplo, os clientes podem chamar getRandomNumber() do servio.
Aqui est uma atividade que se liga a LocalService e solicita getRandomNumber()
quando um boto clicado:
public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
ANDROID, uma viso geral Anderson Duarte de Amorim
89
unbindService(mConnection);
mBound = false;
}
}

/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}

/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}

@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
O exemplo acima mostra como o cliente liga para o servio usando uma implementao
do ServiceConnection e o callback de onServiceConnected().
Nota: O exemplo acima no explicitamente desvinculado do servio, mas todos os
clientes devem desvincular em um tempo adequado (por exemplo, quando a atividade
pausa).

ANDROID, uma viso geral Anderson Duarte de Amorim
90
Usando um Messenger
Se voc precisar de seu servio para se
comunicar com processos remotos,
ento voc pode usar um Messenger
para fornecer a interface para o servio.
Esta tcnica permite realizar a
comunicao entre processos (IPC),
sem a necessidade de utilizar AIDL.
Aqui est um resumo de como usar um
Messenger:
O servio implementa um
Handler que recebe um callback
para cada chamada de um
cliente.
O Handler usado para criar uma Messenger (que uma referncia para o
Handler).
O Messenger cria um IBinder que o servio retorna para clientes de onBind().
Os clientes usam o IBinder para instanciar o Messenger (que faz referncia ao
servio Handler), que o cliente usa para enviar mensagens para o servio.
O servio recebe cada mensagem em seu Handler, especificamente, no mtodo
handleMessage().
Desta forma, no existem "mtodos" para o cliente para chamar o servio. Em vez
disso, o cliente fornece as "mensagens" (objetos Message) que o servio recebe em seu
Handler.
Aqui est um exemplo de servio simples que usa um Messenger interface:
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;

/**
* Handler of incoming messages from clients.
Comparado com AIVD
Quando voc precisa realizar IPC, utilizar um
Messenger para a sua interface mais simples do
que implement-la com AIDL, porque Messenger
enfilera todas as chamadas para o servio, que,
uma interface AIDL pura envia pedidos
simultneos para o servio, que deve, ento, lidar
com multi-threading.
Para a maioria das aplicaes, o servio no
precisa executar multi-threading, portanto, usar
um Messenger permite ao servio lidar com uma
chamada ao mesmo tempo. Se importante que o
seu servio seja multi-threaded, ento voc deve
usar AIDL para definir sua interface.
ANDROID, uma viso geral Anderson Duarte de Amorim
91
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!",
Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}

/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());

/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
Observe que o mtodo handleMessage() no Handler onde o servio recebe a entrada
Message e decide o que fazer, com base no membro what.
Tudo o que um cliente precisa fazer criar um Messenger com base no IBinder
retornado pelo servio e enviar uma mensagem usando o send(). Por exemplo, aqui
uma atividade simples, que liga para o servio e oferece a mensagem
MSG_SAY_HELLO para o servio:
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;

/** Flag indicating whether we have called bind on the service. */
boolean mBound;

/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
ANDROID, uma viso geral Anderson Duarte de Amorim
92
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}

public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};

public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
ANDROID, uma viso geral Anderson Duarte de Amorim
93
Observe que este exemplo no mostra como o servio pode responder ao cliente. Se
voc deseja que o servio responda, ento voc tambm precisa criar um Messenger no
cliente. Ento, quando o cliente recebe a chamada onServiceConnected(), ele envia uma
mensagem para o servio, que inclui o Messenger do cliente no parmetro replyTo d
mtodo send().
Voc pode ver um exemplo de como fornecer mensagens bidirecionais no
MessengerService.java (servio) e MessengerServiceActivities.java (cliente).
Vinculao a um servio
Componentes da aplicao (clientes) podem se ligar a um servio chamando
bindService(). O sistema Android, em seguida, chama o servio de onBind(), mtodo
que retorna um IBinder para interagir com o servio.
A ligao assncrona, bindService() retorna imediatamente e no retorna a IBinder
para o cliente. Para receber o IBinder, o cliente deve criar uma instncia de
ServiceConnection e o passa para bindService(). O ServiceConnection inclui um
mtodo de resposta que o sistema chama para entregar o IBinder.
Nota: S as atividades, servios e provedores de contedo podem se ligar a um servio
- voc no pode seligar a um servio a partir de um receptor de broadcast.
Assim, para ligar a um servio de seu cliente, voc deve:
1. Implementar ServiceConnection .
A implementao deve substituir dois mtodos:
onServiceConnected(): O sistema chama isso para entregar o IBinder retornado
pelo mtodo onBind() do servio.
onServiceDisconnected(): O sistema Android chama isso quando a conexo
com o servio perdida inesperadamente, como quando o servio foi paralisada
ou tenha sido morta. Isto no chamado quando o cliente libera.
2. Call bindService(), passando a implementao ServiceConnection.
ANDROID, uma viso geral Anderson Duarte de Amorim
94
3. Quando o sistema chama o mtodo de retorno onServiceConnected(), voc pode
comear a fazer chamadas para o servio, utilizando os mtodos definidos pela
interface.
4. Para desligar do servio, chame unbindService().
Quando o cliente for destrudo, ele ir desvincular-se do servio, mas voc deve
sempre desvincular quando terminar a interao com o servio ou quando a
atividade pausar, ento o servio pode parar enquanto no est sendo utilizado.
Por exemplo, o seguinte trecho liga o cliente ao servio criado anteriormente por
estender a classe Binder, ento tudo o que deve fazer o lanar o IBinder retornado ao
LocalService e solicitar a LocalService:
LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}

// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "onServiceDisconnected");
mBound = false;
}
};
Com este ServiceConnection, o cliente pode ligar para um servio, passando este para
bindService(). Por exemplo:
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
O primeiro parmetro de bindService() uma Intent que, explicitamente, nomeia
o servio a ser vinculado (pensando que a inteno pode ser implcita).
O segundo parmetro o objeto ServiceConnection.
O terceiro parmetro um sinalizador que indica as opes para a ligao. Deve
ser geralmente BIND_AUTO_CREATE, a fim de criar o servio se ainda no
ANDROID, uma viso geral Anderson Duarte de Amorim
95
estiver vivo. Outros valores possveis so BIND_DEBUG_UNBIND e
BIND_NOT_FOREGROUND, ou 0 para nenhum.
Notas adicionais
Aqui esto algumas anotaes importantes sobre a ligao a um servio:
Voc deve sempre lanar excees DeadObjectException, que so lanados
quando a conexo foi quebrada. Esta a nica exceo acionada por mtodos
remotos.
Os objetos so referncia contada atravs de processos.
Voc normalmente dever emparelhar a ligao e desligamento durante a
correspondente destruio e desmontagem de momentos do ciclo de vida do
cliente. Por exemplo:
o Se voc s precisa interagir com o servio, enquanto sua atividade
visvel, voc deve se ligar durante onStart() e desvincular durante
onStop().
o Se voc quiser que a sua atividade receba as respostas, mesmo quando
ele est parado no fundo, ento voc pode se ligar durante onCreate() e
desvincular durante onDestroy(). Cuidado com o que isso implica que a
sua atividade necessita para usar o servio durante todo o tempo ele est
rodando (mesmo no fundo), por isso, se o servio est em outro processo,
ento voc aumentar o peso do processo e torna-se mais provvel do
sistema mat-lo.
Nota: Voc normalmente no deveria vincular e desvincular a sua atividade durante o
onResume() e onPause(), porque esses retornos ocorrem em todas as transies do
ciclo de vida e voc deve manter o processamento que ocorre nessas transies para
um nvel mnimo. Alm disso, se h vrias atividades em sua aplicao para vincular o
mesmo servio e no h uma transio entre duas dessas atividades, o servio pode ser
destrudo e recriado como desassocia a atividade atual (durante a pausa) antes da
prxima ligao (durante a retomada).

ANDROID, uma viso geral Anderson Duarte de Amorim
96
Gerenciando o ciclo de vida de um servio de
associao

Figura 1. O ciclo de vida de um servio que iniciado e tambm permite a ligao.
Quando um servio desvinculado de todos os clientes, o sistema Android o destri (a
menos foi iniciado com onStartCommand()). Como tal, voc no tem que gerenciar o
ciclo de vida do seu servio se ele meramente um limite de servio - o sistema
Android gerencia isso para voc saber se ele est ligado a algum cliente.
No entanto, se voc optar por implementar o mtodo de retorno onStartCommand(),
ento voc deve explicitamente parar o servio, porque o servio considerado agora a
ANDROID, uma viso geral Anderson Duarte de Amorim
97
ser iniciado. Neste caso, o servio executado at que o servio para com stopSelf() ou
outro componente chama stopService(), independentemente se est ligado a outros
clientes.
Alm disso, se o servio iniciado e aceita a ligao, ento quando o sistema solicita
sua onUnbind(), voc pode opcionalmente retornar true se voc gostaria de receber uma
chamada para onRebind() na prxima vez que um cliente chama o servio (ao invs de
receber uma chamada para onBind()). onRebind() retorna void, mas o cliente ainda
recebe o IBinder na sua onServiceConnected(). A figura 1 ilustra a lgica para este tipo
de ciclo de vida.

ANDROID, uma viso geral Anderson Duarte de Amorim
98
Processos e threads
Quando um componente de aplicativo se inicia e a aplicao no possui nenhum outro
componente rodando, o sistema Android inicia um novo processo Linux para a
aplicao com um nico thread. Por padro, todos os componentes do mesmo aplicativo
executam no mesmo processo e thread (chamada de thread "main"). Se um componente
do aplicativo iniciado e j existe um processo para aquela aplicao (porque um outro
componente do aplicativo existe), ento o componente iniciado dentro desse processo
e usa o mesmo thread de execuo. No entanto, voc pode arranjar para diferentes
componentes em seu aplicativo para serem executados em processos separados, e voc
pode criar threads adicionais para qualquer processo.
Processos
Por padro, todos os componentes do mesmo aplicativo executam no mesmo processo e
a maioria das aplicaes no devem mudar isso. No entanto, se voc achar que voc
precisa controlar a que processo um determinado componente pertence, pode faz-lo no
arquivo de manifesto.
A entrada de manifesto para cada tipo de elemento - <activity>, <service , <receiver> e
<provider> - suporta um atributo android:process que pode indicar um processo em que
esse componente deve ser executado. Voc pode definir esse atributo para que cada
componente seja executado em seu prprio processo, ou que algumas componentes
compartilham um processo, enquanto outros no. Voc tambm pode definir
android:process de modo que os componentes de diferentes aplicaes sejam
executados no mesmo processo - desde que as aplicaes compartilhem o mesmo ID de
usurio do Linux e assinem com os mesmos certificados.
O elemento <application> tambm suporta um atributos android:process, para definir
um valor padro que se aplica a todos os componentes.
Android pode decidir encerrar um processo em algum momento, quando houver pouca
memria e exigido por outros processos que esto mais imediatamente servindo ao
usurio. Componentes de aplicativos em execuo no processo que est morto so
conseqentemente destrudos. Um processo iniciado novamente para esses
componentes, quando h trabalho novamente para que eles faam.
ANDROID, uma viso geral Anderson Duarte de Amorim
99
Ao decidir quais os processos matar, o sistema Android pesa a sua importncia relativa
para o usurio. Por exemplo, mais facilmente desligado um processo hospedando
atividades que no so mais visveis na tela, em comparao com um processo
hospedando atividades visveis. A deciso de encerrar um processo, portanto, depende
do estado dos componentes em execuo no processo.
Ciclo de vida do processo
O sistema Android tenta manter um processo de candidatura pelo maior tempo possvel,
mas, eventualmente, precisa remover os processos antigos para recuperar a memria
para novos processos ou mais importantes. Para determinar quais os processos manter e
quais matar, o sistema coloca cada processo em uma "hierarquia de importncia" com
base nos componentes em execuo no processo e o estado desses componentes.
Processos com menor importncia so eliminadas em primeiro lugar, em seguida,
aqueles com a menor importncia seguinte, e assim por diante, sempre que necessrio
para recuperar os recursos do sistema.
H cinco nveis na hierarquia de importncia. A lista a seguir apresenta os diferentes
tipos de processos em ordem de importncia (o primeiro processo o mais importante e
morto por ltimo):
1. Processo em primeiro plano: Um processo que necessrio para que o usurio
esteja fazendo atualmente. Um processo considerado em primeiro plano, se
qualquer uma das seguintes condies forem verdadeiras:
Abriga uma Activity com a qual o usurio est interagindo com (o
mtodo onResume() da Activity foi chamado).
Abriga um Service que est vinculado atividade que o usurio est
interagindo.
Abriga um Service que est sendo executado "em primeiro plano", o
servio chamado startForeground().
Abriga um Service que est executando um ciclo de vida de seus retornos
(onCreate(), onStart(), ou onDestroy()).
Abriga um BroadcastReceiver que est executando a sua onReceive().
Geralmente, apenas um processo de background existe em um determinado
momento. Eles so mortos apenas como um ltimo recurso - se a memria to
ANDROID, uma viso geral Anderson Duarte de Amorim
100
pouca que ele no pode continuar rodando. Geralmente, nesse ponto, o
dispositivo atingiu um estado de paginao de memria, ento, matar alguns
processos de primeiro plano necessrio para manter a interface de usurio
sensvel.
2. Processo Visvel
Um processo que no tem nenhum componente de primeiro plano, mas ainda
pode afetar o que o usurio v na tela. Um processo considerado visvel se
qualquer uma das seguintes condies forem verdadeiras:
Abriga uma Activity que no est em primeiro plano, mas ainda visvel
para o usurio (seu mtodo onPause() foi chamado). Isso pode ocorrer,
por exemplo, se a atividade iniciou um plano de dilogo, que permite que
a atividade anterior possa ser vista por trs dele.
Abriga um Service que est vinculado a uma atividade (ou plano) visvel.
Um processo visvel considerado extremamente importante e no vai ser morto
a menos que isso necessrio para manter todos os processos de primeiro plano
em execuo.
3. Processo de servio
Um processo que est executando um servio que foi iniciado com o mtodo
startService() e no se enquadra em nenhuma das duas categorias acima. Embora
os processos de servio no estejam diretamente ligados a qualquer coisa que o
usurio v, eles esto geralmente fazendo coisas que o usurio se preocupa
(como a reproduo de msica no fundo ou baixando arquivo na rede), ento o
sistema os mantm rodando, a menos que no haja memria suficiente para ret-
los, juntamente com o primeiro plano e processos visveis.
4. Processo em segundo plano
Um processo que mantm uma atividade que no visvel para o usurio no
momento (o mtodo onStop() da atividade foi chamado). Esses processos no
tm impacto direto sobre a experincia do usurio, e o sistema pode mat-los a
qualquer momento para recuperar a memria para primeiro plano, visibilidade,
ou processo de servio. Normalmente, h muitos processos em execuo no
ANDROID, uma viso geral Anderson Duarte de Amorim
101
fundo, ento eles so mantidos em uma LRU (menos recentemente usada), lista
para garantir que o processo com a atividade que mais recentemente foi visto
pelo usurio o ltimo a ser morto. Se uma atividade implementa mtodos de
seu ciclo de vida corretamente, e salva o seu estado atual, matar o seu processo
no ter um efeito visvel sobre a experincia do usurio, pois quando o usurio
navega de volta para a atividade, a atividade restaura todo o seu estado visvel.
5. Processo vazio
Um processo que no possui todos os componentes do aplicativo ativos. A nica
razo para manter esse tipo de processo vivo para fins de armazenamento em
cache, para melhorar o tempo de inicializao da prxima vez que um
componente precisa ser executado. O sistema mata muitas vezes estes processos
a fim de equilibrar os recursos do sistema global entre os caches do processo e
os cachs do kernel subjacente.
Android enfileira um processo ao mais alto nvel que pode, com base na importncia do
componente ativo no processo. Por exemplo, se um processo hospeda um servio e uma
atividade visvel, o processo classificado como um processo visvel, e no um
processo de servio.
Alm disso, o ranking de um processo pode ser acrescido, pois outros processos so
dependentes dele - um processo que est servindo a outro processo nunca pode ser
menor classificado do que o processo que est servindo. Por exemplo, se um provedor
de contedo em um processo A est a servir um cliente no processo de B, ou se um
servio em um processo A est ligado a um componente no processo de B, processo A
sempre considerado pelo menos to importante como o processo B.
Porque um processo executando um servio melhor classificado do que um processo
com atividades em segundo plano, uma atividade que inicia uma operao de longa
durao pode muito bem comear um servio para essa operao, ao invs de
simplesmente criar uma thread de trabalhador - particularmente se a operao
provavelmente durar mais que a atividade. Por exemplo, uma atividade que carrega
uma foto em um site deve iniciar um servio para realizar o upload, ento o upload pode
continuar em segundo plano, mesmo se o usurio deixar a atividade. Usar um servio
garante que a operao ter, pelo menos, prioridade "no processo do servio",
ANDROID, uma viso geral Anderson Duarte de Amorim
102
independentemente do que acontece com a atividade. Este o mesmo motivo que os
receptores de broadcast devem contratar servios ao invs de simplesmente colocar
operaes demoradas em um thread.
Thread
Quando uma aplicao lanada, o sistema cria um thread de execuo para o
aplicativo, chamado de "main". Esta thread muito importante, pois responsvel por
despachar os eventos para os apropriados widgets de interface de usurio, incluindo
eventos de desenho. tambm o segmento em que sua aplicao interage com os
componentes da UI Toolkit Android (componentes da android.widget e pacotes
android.view). Como tal, o thread principal chamado tambm s vezes de UI thread.
O sistema no cria um thread separado para cada instncia de um componente. Todos os
componentes que so executados no mesmo processo so instanciados no thread de
interface do usurio e as chamadas do sistema para cada componente so despachadas a
partir desse thread. Conseqentemente, os mtodos que respondem s callbacks do
sistema (como onKeyDown() para relatar as aes do usurio ou um mtodo de retorno
do ciclo de vida) sempre executam no thread da interface do usurio do processo.
Por exemplo, quando o usurio toca um boto na tela, seu thread UI do aplicativo
despacha o evento de toque para o widget, que por sua vez, define seu estado
pressionado e lana uma requisio invlida para a fila de eventos. O thread UI
desenfilera a requisio e notifica o widget que deve se redesenhar.
Quando o aplicativo executa um trabalho intensivo em resposta interao do usurio,
este nico thread pode produzir mal desempenho a menos que voc implemente a sua
aplicao de forma adequada. Especificamente, se tudo est acontecendo no thread de
interface do usurio, realizando longas operaes, tais como acesso rede ou consultas
de banco de dados, ir bloquear a interface toda. Quando o thread est bloqueado,
nenhum evento pode ser enviado, incluindo eventos de desenho. Do ponto de vista do
usurio, o aplicativo parece travar. Pior ainda, se o segmento de interface do usurio
estiver bloqueado por mais de alguns segundos (cerca de 5 segundos atualmente) ao
usurio apresentado o abominvel "aplicativo no responde" (ANR). O usurio pode,
ento, decidir abandonar a aplicao e desinstal-la se est infeliz.
ANDROID, uma viso geral Anderson Duarte de Amorim
103
Alm disso, o Andoid UI Toolkit no thread-safe. Ento, voc no deve manipular a
sua interface a partir de um thread de trabalho - voc deve fazer toda a manipulao de
sua interface a partir de um thread UI. Assim, existem apenas duas regras para o modelo
de thread nica no Android:
1. No bloquear o thread de UI
2. No acessar o Android UI Toolkit de fora do thread UI
Threads funcionais
Devido ao modelo de thread nico acima descrito, vital para a capacidade de resposta
da interface do usurio do seu aplicativo que voc no bloqueie o thread. Se voc tiver
de realizar operaes que no so instantneas, voc deve certificar-se de faz-las em
threads separados ("background" ou threads "worker").
Por exemplo, abaixo est um cdigo para um usurio que faz o download de uma
imagem de um thread separado e exibida em uma ImageView:
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
mImageView.setImageBitmap(b);
}
}).start();
}
Em princpio, isso parece funcionar bem, porque cria uma nova thread para lidar com a
operao da rede. No entanto, ele viola a segunda regra do modelo de nica thread: no
acessar o Android UI Toolkit de fora da UI-thread - esta amostra modifica o
ImageView do thread de trabalho em vez do thread UI. Isso pode resultar em um
comportamento indefinido e inesperado, que pode ser difcil e demorado para rastrear.
Para corrigir esse problema, o Android oferece vrias maneiras para acessar a thread de
interface do usurio a partir de outros threads. Aqui est uma lista de mtodos que
podem ajudar:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
ANDROID, uma viso geral Anderson Duarte de Amorim
104
Por exemplo, voc pode corrigir o cdigo acima usando o mtodo
View.post(Runnable):
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
mImageView.post(new Runnable() {
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
}).start();
}
Agora, essa implementao thread-safe: o funcionamento da rede feito a partir de
um segmento separado, enquanto o ImageView manipulado a partir do thread de
interface de usurio.
No entanto, como a complexidade da operao cresce, este tipo de cdigo pode ser
complicado e difcil de manter. Para lidar com interaes mais complexas com um
thread de trabalho, voc pode considerar usar um Handler, para processar as mensagens
entregues a partir do thread. Talvez a melhor soluo, porm, estender a classe
AsyncTask, o que simplifica a execuo de tarefas do thread de trabalho que precisam
interagir com a interface do usurio.
Usando AsyncTask
AsyncTask permite executar trabalho assncrono em sua interface com o usurio. Ela
executa as operaes de bloqueio em um segmento de trabalho e, em seguida, publica os
resultados no segmento de interface do usurio, sem que voc precise lidar com tpicos
e/ou manipuladores de si mesmo.
Para us-lo, voc deve incorporar AsyncTask e implementar o mtodo de retorno
doInBackground(), que executado em um pool de threads de background. Para
atualizar sua interface, voc deve implementar onPostExecute(), que fornece o resultado
da doInBackground() e executado no thread da interface do usurio, assim voc pode
escolher atualizar o UI. Voc pode ento executar a tarefa, chamando execute() do
thread UI.
ANDROID, uma viso geral Anderson Duarte de Amorim
105
Por exemplo, voc pode implementar o exemplo anterior usando AsyncTask desta
forma:
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to AsyncTask.execute() */
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}

/** The system calls this to perform work in the UI thread and delivers
* the result from doInBackground() */
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
Agora a interface do usurio segura e o cdigo simples, porque separa o trabalho na
parte que deve ser feita em um thread de trabalho e a parte que deve ser feita no thread
de interface de usurio.
Voc deve ler o AsyncTask de referncia para um entendimento completo de como usar
essa classe, mas aqui est uma viso geral de como funciona:
Voc pode especificar o tipo dos parmetros, os valores de progresso e o valor
final da tarefa, usando genricos
O mtodo doInBackground() executado automaticamente em um segmento de
trabalho
onPreExecute(), onPostExecute(), e onProgressUpdate() so invocados no thread
de interface do usurio
O valor retornado por doInBackground() enviado para onPostExecute()
Voc pode chamar publishProgress() em qualquer outro momento do
doInBackground() para executar onProgressUpdate() na thread da UI
Voc pode cancelar a tarefa a qualquer hora, de qualquer thread
Ateno: Outro problema que se pode encontrar ao usar um segmento de trabalho
reincios inesperados na sua atividade devido a uma alterao de configurao em
tempo de execuo (como quando o usurio muda a orientao da tela), que podem
ANDROID, uma viso geral Anderson Duarte de Amorim
106
destruir seu segmento de trabalho. Para ver como voc pode manter a sua tarefa
durante um desses reincios e como fazer corretamente um cancelamento da tarefa
quando a atividade for destruda, veja o cdigo fonte para o aplicativo de amostra da
Prateleira.
Mtodos de Thread-safe
Em algumas situaes, os mtodos a implementar poderiam ser chamados de mais de
um thread e, portanto, deve ser escrito para ser thread-safe.
Isto principalmente verdadeiro para mtodos que podem ser chamados remotamente,
como mtodos de um servio vinculado. Quando uma chamada de um mtodo
implementado em um IBinder se origina no mesmo processo em que o IBinder est
executando, o mtodo executado na thread de quem chamou. No entanto, quando a
chamada originada em outro processo, o mtodo executado em um thread escolhido
de um pool de threads que o sistema mantm no mesmo processo que o IBinder (no
executado no thread da interface do usurio do processo). Por exemplo, considerando
que um mtodo onBind() do servio seria chamado do de interface do usurio do
processo de servio, mtodos implementados no objeto que onBind() retorna (por
exemplo, uma subclasse que implementa mtodos RPC) seriam chamados threads no
pool. Como um servio pode ter mais de um cliente, mais de uma pool de threads pode
envolver o mesmo mtodo IBinder, ao mesmo tempo. Mtodos IBinder devem,
portanto, ser implementadas para ser thread-safe.
Da mesma forma, um provedor de contedo pode receber dados de pedidos que se
originam em outros processos. Embora o ContentResolver e ContentProvider ocultam
os detalhes de como a comunicao entre processos gerenciada, mtodos
ContentProvider que respondem a esses pedidos - os mtodos query(), insert(), delete(),
update(), e getType() so chamados a partir de um pool de threads no processo de
provedor de contedo, e no o thread UI para o processo. Como esses mtodos podem
ser chamados a partir de qualquer nmero de threads ao mesmo tempo, eles tambm
devem ser implementados para ser thread-safe.
Comunicao entre processos
Android oferece um mecanismo para comunicao entre processos (IPC) atravs de
chamadas de procedimento remoto (RPCs), em que um mtodo chamado por uma
ANDROID, uma viso geral Anderson Duarte de Amorim
107
atividade ou um componente de outro aplicativo, mas executado remotamente (em outro
processo), com qualquer resultado retornado de volta para o chamador. Isto implica a
decomposio de uma chamada de mtodo e de seus dados a um nvel que o sistema
operacional possa entender, transmiti-lo a partir do processo do processo local e espao
de endereamento para o processo remoto e espao de endereo, em seguida, remontar e
reencenar a chamada. Os valores de retorno so transmitidos na direo oposta.
Android fornece todo o cdigo para executar essas operaes IPC, para que voc possa
se concentrar na definio e implementao da interface de programao do RPC.
Para executar o IPC, o aplicativo deve ligar para um servio, utilizando bindService().

ANDROID, uma viso geral Anderson Duarte de Amorim
108
Interface de usurio
Em um aplicativo do Android, a interface do usurio construda usando objetos View
e ViewGroup. Existem muitos tipos de views e view groups, cada um dos quais um
descendente da classe View.
Objetos view so as unidades bsicas de expresso da interface do usurio na
plataforma Android. A classe View serve como base para as subclasses chamadas de
"widgets", que oferecem completa implementao de objetos de interface do usurio,
como campos de texto e botes. A classe ViewGroup serve como base para as
subclasses chamadas de "layouts", que oferecem diferentes tipos de layout de
arquitetura, como a linear, tabular e relativa.
Um objeto View uma estrutura de dados, cujas propriedades armazenam os
parmetros de layout e de contedo para uma determinada rea retangular da tela. Um
objeto View lida com sua prpria medida, layout, desenho, mudana de foco, scrolling e
interaes telcla/gesto para a rea retangular da tela na qual ele reside. Como um objeto
na interface do usurio, uma View tambm um ponto de interao para o usurio e o
receptor de eventos de interao.
Hierarquia de view
Sobre a plataforma Android, voc define uma interface de atividades, usando uma
hierarquia de view e ns ViewGroup, como mostrado no diagrama abaixo. Esta rvore
de hierarquia pode ser to simples ou complexa como voc precisa que ela seja, e voc
pode constru-la usando o conjunto do Android de widgets e layouts pr-definidos, ou
com views customizados que voc mesmo cria.
ANDROID, uma viso geral Anderson Duarte de Amorim
109

A fim de fixar a rvore de hierarquia de views tela para renderizao, sua atividade
deve chamar o mtodo setContentView() e passar uma referncia ao objeto n raiz. O
sistema Android recebe esta referncia e usa-o para invalidar, medir e desenhar a
rvore. O n raiz da hierarquia requisita que seus ns filhos desenhem a si prprios - por
sua vez, cada n do ViewGroup responsvel por chamar cada um de seus views filhos
para desenhar a si mesmos. Os filhos podem solicitar um tamanho e localizao com os
pais, mas o objeto-me tem a deciso final sobre onde e qual o tamanho que cada
criana pode ter. Android analisa os elementos do layout em ordem (a partir do topo da
rvore de hierarquia), instanciando os Views e adicionando-os aos seus pais. Porque
estes so desenhados em ordem, se h elementos que se sobrepem posies, o ltimo a
ser elaborado vai ficar em cima dos outros previamente elaborados para aquele espao.
Como o Android desenha views
Quando uma atividade recebe o foco, ela ser convidada a desenhar o layout. O
framework Android vai lidar com o processo de elaborao, mas a atividade deve
apresentar o n raiz da sua hierarquia de layout.
Desenho comea com o n raiz do layout. solicitado para medir e desenhar a rvore
de layout. Desenho tratado pelo p da rvore e renderizao de cada vista que cruza a
regio invlida. Por sua vez, cada grupo View responsvel por solicitar a cada um dos
seus filhos a ser desenhado (com o mtodo draw()) e cada View responsvel pelo
desenho de si. Como a rvore percorrida em ordem, isso significa que os pais sero
desenhados antes do que seus filhos, com irmos elaborados na ordem em que aparecem
na rvore.
ANDROID, uma viso geral Anderson Duarte de Amorim
110
Desenhar o layout um processo de duas passagens: a passagem de medidas e uma
passagem de layout. A passagem de medio implementada com measure(int, int) e
uma passagem top-down da rvore. Cada view empurra as especificaes de dimenso
para baixo na rvore durante a recursividade. No final da passagem de medidas, cada
View tem armazenado suas medidas. A segunda fase acontece no layout(int, int, int, int)
e tambm top-down. Durante o passar, cada pai responsvel pelo posicionamento de
todos os seus filhos usando os tamanhos computados na passagem de medidas.
Durante um mtodo de retorno measure() da view, os valores getMeasuredWidth() e
getMeasuredHeight() devem ser definidos, juntamente com as de todos os descendentes
da view. Os valores de medio de largura e altura da view devem respeitar as restries
impostas pelos pais da view. Isso garante que, no final da passagem de medidas, todos
os pais aceitam todas as medies de seus filhos. Um pai view pode chamar measure()
mais de uma vez sobre seus filhos. Por exemplo, os pais podem medir cada filho uma
vez com dimenses no especificadas para descobrir o quo grande eles querem ser,
ento chama measure() neles novamente com nmeros reais, se a soma dos tamanhos
dos filhos irrestrita muito grande ou muito pequena (Ou seja, se os filhos no
concordam entre si a respeito de quanto espao cada um ganha, o pai vai intervir e
estabelecer as regras na segunda passagem).
A passagem de medidas utiliza duas classes para
comunicar dimenses. A classe
View.MeasureSpec usada por views para
contar aos pais como eles querem ser medidos e
posicionados. A classe base LayoutParams
apenas descreve quo grandes as views querem
ser para a largura e altura. Para cada dimenso, pode especificar um dos seguintes:
um nmero exato
FILL_PARENT, o que significa que o view quer ser to grande quanto
seu pai (menos padding)
WRAP_CONTENT, o que significa que o view quer ser grande o
suficiente para colocar o seu contedo (mais padding).
Para dar incio a um esquema, chama-
se requestLayout(). Este mtodo
normalmente chamado por uma view
sobre si mesma quando se acredita que
possvel no caber mais dentro de
seus limites atuais.
ANDROID, uma viso geral Anderson Duarte de Amorim
111
H subclasses de LayoutParams para diferentes subclasses de ViewGroup. Por exemplo,
RelativeLayout tem a sua prpria subclasse de LayoutParams, que inclui a capacidade
de centralizar os filhos horizontalmente e verticalmente.
MeasureSpecs so usados para empurrar os requisitos para baixo da rvore de pai para
filho. Um MeasureSpec pode estar em um dos trs modos:
NO ESPECIFICADO: Isto usado por um dos pais para determinar a
dimenso desejada de um filho View. Por exemplo, um LinearLayout
pode chamar measure() em seu filho com a altura indefinida e uma
largura de exatamente 240.
EXATAMENTE: Este usado pelos pais para impor um tamanho exato
sobre a criana. A criana deve usar esse tamanho, e garante que todos os
seus descendentes se encaixem dentro desse tamanho.
NO MXIMO: Este usado pelos pais para impor um tamanho mximo
para a criana. A criana deve garantir que ele e todos os seus
descendentes vo caber dentro deste tamanho.
Layout
A maneira mais comum para definir o seu layout e expressar a hierarquia de view com
um arquivo de layout XML. XML oferece uma estrutura legvel para o layout, muito
parecido com HTML. Cada elemento em XML ou um View ou ViewGroup (ou
descendentes dos mesmos). Objetos view so folhas da rvore, objetos ViewGroup so
ramos da rvore.
O nome de um elemento XML respectivo para a classe Java que representa. Assim,
um elemento <TextView> cria um na sua interface do usurio, e um elemento
<LinearLayout> cria um ViewGroup. Quando voc carregar um recurso de layout, o
sistema Android inicializa esses objetos em tempo de execuo, correspondentes aos
elementos em seu layout.
Por exemplo, um layout simples vertical, com um text view e um boto parece com
este:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
ANDROID, uma viso geral Anderson Duarte de Amorim
112
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView" />
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button" />
</LinearLayout>
Observe que o elemento LinearLayout contm o TextView e o Boto. Voc pode
aninhar outro LinearLayout (ou outro tipo de grupo de exibio) aqui dentro, para
alongar a hierarquia de view e criar um layout mais complexo.
Dica: Voc tambm pode desenhar View e ViewGroups em cdigo Java, utilizando
mtodos para inserir dinamicamente novos objetos View e ViewGroup.
H uma variedade de maneiras em que voc pode formatar os seus view. Usando mais
tipos diferentes de grupos de exibio, voc pode estruturar views herdados e view
groups em um nmero infinito de maneiras. Alguns view groups pr-definidos
oferecidas pelo Android (chamando layouts) incluem LinearLayout, RelativeLayout,
TableLayout, GridLayout e outros. Cada um oferece um conjunto exclusivo de
parmetros de layout que so usados para definir as posies das views herdadas e a
estrutura de layout.
To learn about some of the different kinds of view groups used for a layout, read . Para
saber mais sobre alguns dos diferentes tipos de grupos de vista usado para um layout,
leia os objetos de layout comum .
Widgets
Um widget um objeto View que serve como uma interface de interao com o usurio.
Android fornece um conjunto de widgets plenamente implementadas, como botes,
caixas de seleo, e os campos de entrada de texto, assim voc pode construir
rapidamente sua interface do usurio. Alguns widgets fornecidos pelo Android so mais
complexos, como um selecionador de data, um relgio, e controles de zoom. Mas voc
no est limitado aos tipos de elementos fornecidos pela plataforma Android. Se voc
quiser fazer algo mais personalizado e criar seus prprios elementos, pode, atravs da
ANDROID, uma viso geral Anderson Duarte de Amorim
113
definio de seu objeto View prprio ou atravs da extenso e combinao de elementos
existentes.

ANDROID, uma viso geral Anderson Duarte de Amorim
114
Eventos UI
Uma vez que voc adicionou alguns views/widgets para a interface do usurio, voc
provavelmente quer saber sobre a interao do usurio com eles, para que voc possa
executar aes. Para ser informado de eventos de interface, voc precisa fazer uma de
duas coisas:
Definir um receptor de evento e registr-lo com a view. Muitas vezes, assim
que voc vai receber os eventos. A classe View contm uma coleo de
interfaces aninhadas nomeadas <something> Listener, cada um com um mtodo
de retorno de chamada On <something>(). Por exemplo, View.OnClickListener
(para lidar com os "cliques" na View), View.OnTouchListener (para lidar com
eventos de tela de toque em uma exibio), e View.OnKeyListener (para lidar
com teclas pressionadas no dispositivo dentro de uma View). Ento se voc quer
sua View para ser notificado quando ela "clicada" (como quando um boto
selecionado), implemente OnClickListener e defina o seu mtodo de retorno
onClick() (onde voc executar a ao aps o clique), e registra-o para a View
com setOnClickListener().
Substituir um mtodo de retorno existente para a View. Isto o que voc
deve fazer quando voc implementou sua prpria classe View e quer receber
eventos especficos que ocorrem dentro dele. Exemplificando eventos voc pode
manipular incluso quando a tela tocada (onTouchEvent()), quando o trackball
movido (onTrackballEvent()), ou quando uma tecla no dispositivo
pressionada (onKeyDown()). Isso permite que voc defina o comportamento
padro para cada evento dentro da sua View personalizada e determinar se o
evento deve ser transmitido para alguma outra View filho. Novamente, essas so
chamadas de retorno para a classe View, assim, sua nica chance de defini-los
quando voc cria um componente personalizado.
Menus
Os menus de aplicativos so outra parte importante da interface do usurio de um
aplicativo. Menus oferecem uma interface confivel, que revela funes de aplicativos e
configuraes. O menu de aplicativos mais comuns revelado, pressionando a tecla
MENU no dispositivo. No entanto, voc tambm pode adicionar menus de contexto,
ANDROID, uma viso geral Anderson Duarte de Amorim
115
que podem ser revelados quando o usurio pressiona e mantm pressionado em um
item.
Os menus tambm so estruturados usando uma hierarquia View, mas voc no define
essa estrutura por si mesmo. Em vez disso, voc define mtodos de retorno como
onCreateOptionsMenu() ou onCreateContextMenu() para a sua atividade, e declara os
itens que voc deseja incluir em seu menu. Em momento oportuno, o Android ir criar
automaticamente a necessria hierarquia View para o menu e desenhar cada um dos
seus itens de menu na mesma.
Menus tambm lidam com seus prprios eventos, por isso no h necessidade de
registrar eventos listeners sobre os itens do seu menu. Quando um item no seu menu
selecionado, o mtodo onOptionsItemSelected() ou onContextItemSelected() ser
chamado pelo framework.
E, assim como o layout do aplicativo, voc tem a opo de declarar os itens para seu
menu em um arquivo XML.
Tpicos Avanados
Uma vez que voc aprendeu os fundamentos da criao de uma interface, voc pode
explorar algumas caractersticas avanadas para a criao de uma interface de aplicao
mais complexa.
Adaptadores
s vezes voc deseja preencher um view group com algumas informaes que no
podem ser codificados, em vez disso, voc quer associar a sua view a uma fonte externa
de dados. Para fazer isso, use um AdapterView como seu grupo de viso e cada filho
view inicializado e preenchido com os dados do adaptador.
O objeto AdapterView uma implementao do ViewGroup que determina as views
dos filhos com base em um determinado adaptador. O adaptador funciona como um
mensageiro entre a fonte de dados (talvez um array de strings externa) e os
AdapterView, que exibe. Existem vrias implementaes da classe Adapter, para tarefas
especficas, como a CursorAdapter para leitura de dados banco de dados de um cursor
ou um ArrayAdapter para a leitura de uma matriz arbitrria.
ANDROID, uma viso geral Anderson Duarte de Amorim
116
Estilos e Temas
Talvez voc no esteja satisfeito com a aparncia dos widgets padro. Para rev-los,
voc pode criar alguns dos seus prprios estilos e temas.
Um estilo um conjunto de um ou mais atributos de formatao que voc pode
aplicar como uma unidade de elementos individuais em seu layout. Por exemplo,
voc pode definir um estilo que especifica um determinado tamanho de texto e
cor, em seguida, aplic-lo apenas a elementos especficos.
Um tema um conjunto de um ou mais atributos de formatao que voc pode
aplicar como uma unidade para todas as atividades em uma aplicao, ou apenas
uma atividade nica. Por exemplo, voc pode definir um tema que define as
cores especficas para a moldura da janela e o fundo do painel, e define o
tamanho dos textos e cores dos menus. Este tema pode ser aplicado a atividades
especficas ou todo o aplicativo.
Estilos e temas so recursos. Android oferece alguns recursos de estilo padro e tema
que voc pode usar, ou voc pode declarar o seu prprio estilo customizado e recursos
de tema.

ANDROID, uma viso geral Anderson Duarte de Amorim
117
Declarando Layout
Seu layout a arquitetura para interface de usurio em uma atividade. Ela define a
estrutura de layout e possui todos os elementos que aparecem para o usurio. Voc pode
declarar o seu layout de duas maneiras:
Declare elementos UI em XML - Android fornece um vocabulrio XML
simples que corresponde s classes View e subclasses, tais como widgets e
layouts.
Instanciar elementos de layout em tempo de execuo - O aplicativo pode
criar objetos de View e ViewGroup (e manipular suas propriedades) de forma
programaticamente.
O framework Android lhe d a flexibilidade para usar um ou ambos os mtodos para
declarar e gerenciar a interface do usurio do seu aplicativo. Por exemplo, voc poderia
declarar layouts padro de seu aplicativo em XML, incluindo os elementos da tela que
aparecero nela e suas propriedades. Voc pode ento adicionar o cdigo em seu
aplicativo que iria alterar o estado dos objetos da tela, incluindo aqueles declarados em
XML, em tempo de execuo.
A vantagem de declarar a sua
interface em XML que ela permite
melhor separar a apresentao da sua
aplicao do cdigo que controla o
seu comportamento. Suas descries
de interface do usurio so externas
sua aplicao, o que significa que
voc pode modific-lo ou adapt-lo
sem ter que modificar seu cdigo-
fonte e recompilar. Por exemplo, voc
pode criar layouts XML para
orientaes de tela diferentes,
diferentes tamanhos de tela do
dispositivo, e lnguas diferentes.
Alm disso, declarar o layout em XML torna mais fcil visualizar a estrutura de sua
O plugin ADT para Eclipse oferece um
preview do seu layout XML - com o
arquivo XML aberto, selecione a guia
Layout.
Voc tambm deve tentar a ferramenta de
Hierarquia Viewer para depurao de
layouts ela revela propriedade de layout,
desenha wireframes com indicadores
padding/margin e view completas
renderizadas enquanto voc depurar no
emulador ou dispositivo.
A ferramenta layoutopt permite analisar
rapidamente os seus layouts e hierarquias
de ineficincias ou outros problemas.
ANDROID, uma viso geral Anderson Duarte de Amorim
118
interface do usurio, por isso mais fcil depurar problemas. Como tal, este documento
centra-se em ensin-lo a declarar o seu layout em XML. Se voc estiver interessado em
instanciar objetos view em tempo de execuo, consulte as classes ViewGroup e View.
Em geral, o vocabulrio XML para a declarao de elementos da interface segue de
perto a estrutura e nomenclatura das classes e mtodos, onde os nomes dos elementos
correspondem aos nomes de classes e nomes de atributos correspondem aos mtodos.
De fato, a correspondncia muitas vezes to direta que voc pode adivinhar o atributo
XML corresponde a um mtodo de classe, ou adivinhar o que a classe corresponde a um
determinado elemento XML. No entanto, note que nem todo vocabulrio idntico. Em
alguns casos, existem ligeiras diferenas de nomenclatura. Por exemplo, o elemento
EditText tem um atributo text que corresponde a EditText.setText() .
Dica: Saiba mais sobre os diferentes tipos de layout em Common Layout Objects.
Escreve o XML
Usando o vocabulrio do Android XML, voc pode rapidamente criar layouts de
interface do usurio e os elementos de tela que eles contm, da mesma forma que voc
cria pginas web em HTML - com uma srie de elementos aninhados.
Cada arquivo de layout deve conter exatamente um elemento de raiz, que deve ser um
objeto de view ou ViewGroup. Depois de definir o elemento raiz, voc pode adicionar
objetos de layout adicionais ou widgets como elementos filho para criar gradualmente
uma hierarquia de exibio que define o layout. Por exemplo, aqui est um esquema
XML que usa um LinearLayout vertical que contm um TextView e um Button :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView" />
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button" />
</LinearLayout>
ANDROID, uma viso geral Anderson Duarte de Amorim
119
Depois de ter declarado o seu layout em XML, salve o arquivo com a extenso .xml em
seu projeto Android no diretrio res/layout/, assim ele vai compilar corretamente.
Carregar os recursos XML
Quando voc compilar sua aplicao, cada arquivo de layout XML compilado em um
View de recurso. Voc deve carregar o recurso de layout de sua aplicao, em sua
implementao de retorno Activity.onCreate(). Faa isso chamando setContentView(),
passando a referncia ao seu recurso de layout na forma de: R.layout. layout_file_name.
Por exemplo, se o seu layout XML salvo como main_layout.xml, voc deve carreg-lo
para a sua atividade da seguinte forma:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
O mtodo de retorno onCreate() em sua atividade chamado pelo framework Android
quando sua atividade lanada.
Atributos
Cada objeto View e ViewGroup apia a sua prpria variedade de atributos XML.
Alguns atributos so especficos para um objeto View (por exemplo, TextView apia o
atributo textSize), mas esses atributos tambm so herdadas por qualquer objetos View
que podem estender esta classe. Alguns so comuns a todos objetos View, porque eles
so herdados da classe View raiz (como o atributo id). E, outros atributos so
considerados "parmetros de layout", que so atributos que descrevem determinadas
orientaes de layout do objeto View.
ID
Qualquer objeto View pode ter um ID de inteiro associado a ele, para identificar o View
dentro da rvore. Quando o aplicativo compilado, essa identificao referenciada
como um inteiro, mas a identificao normalmente atribuda no layout do arquivo
XML como uma string, no atributo id. Este um atributo XML comum a todos os
objetos View (definido pela classe View) e voc vai us-lo muitas vezes. A sintaxe para
uma identificao, dentro de uma tag XML :
ANDROID, uma viso geral Anderson Duarte de Amorim
120
android:id="@+id/my_button"
O smbolo de arroba (@) no incio da string indica que o analisador XML deve analisar
e ampliar o resto da seqncia de identificao e identific-lo como um recurso de
identificao. O sinal de mais (+) significa que este um novo nome de recurso que
deve ser criado e adicionado aos nossos recursos (no arquivo R.java). H uma srie de
recursos de outro tipo de identificao que so oferecidos pela estrutura do Android. Ao
fazer referncia a uma identificao de recurso Android, voc no precisa do sinal de
mais, mas deve adicionar o namespace de pacote android, assim:
android:id="@android:id/empty"
Com o namespace de pacote android no lugar, agora estamos fazendo referncia a uma
ID da classe de recursos android.R, ao invs da classe de recursos locais.
A fim de criar views e referenci-los a partir da aplicao, um padro comum :
1. Definir uma view/widget no arquivo de layout e atribuir um ID nico:
<Button android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
2. Em seguida, crie uma instncia do objeto view e capture-o a partir do layout
(geralmente no mtodo onCreate()):
Button myButton = (Button) findViewById(R.id.my_button);
Definir os IDs dos objetos view importante ao criar um RelativeLayout. Em um
RelativeLayout, views irmos podem definir a sua disposio em relao a outro view
irmo, que referenciada pela ID exclusiva.
Uma identificao no precisa ser nica para toda a rvore, mas deve ser exclusiva
dentro da parte da rvore que voc est procurando (o que pode muitas vezes ser a
rvore inteira, por isso melhor ser completamente original quando possvel).
Parmetros de layout
Atributos de layout XML chamados layout_something definem os parmetros de layout
para a view que sejam adequadas para a ViewGroup em que ele reside.
ANDROID, uma viso geral Anderson Duarte de Amorim
121
Cada classe ViewGroup implementa uma classe aninhada que estende
ViewGroup.LayoutParams. Esta subclasse contm os tipos de propriedades que definem
o tamanho e a posio de cada view filha, conforme apropriado para o view group.
Como voc pode ver na figura 1, o grupo de exibio pai define os parmetros de layout
para cada view filho (incluindo o view group dos filhos).

Figura 1. Visualizao de uma hierarquia de views com os parmetros de layout associado a cada
exibio.
Note que cada subclasse LayoutParams tem sua prpria sintaxe para definir valores.
Cada elemento filho deve definir LayoutParams que so apropriadas para seu pai,
embora possa tambm definir LayoutParams diferentes para seus filhos.
Todos os view groups incluem uma largura e altura (layout_width e layout_height), e
cada view necessria para defini-los. Muitos LayoutParams tambm incluem margens
opcional e fronteiras.
Voc pode especificar a largura e altura com medidas exatas, embora voc
provavelmente no ir querer fazer isso com freqncia. Mais freqentemente, voc vai
usar uma dessas constantes para definir a largura ou altura:
wrap_content diz a seu view a arranjar a si prprio para as dimenses exigidas
pelo seu contedo.
ANDROID, uma viso geral Anderson Duarte de Amorim
122
fill_parent (rebatizada match_parent na API Nvel 8) diz sua view para se
tornar to grande quanto o view group dos pais ir permitir.
Em geral, especificar uma largura de layout e altura, utilizando unidades absolutas, tais
como pixels no recomendada. Em vez disso, por meio de medidas como a densidade
relativa independente unidades de pixel (DP), wrap_content ou fill_parent, uma
abordagem melhor, porque ajuda a garantir que seu aplicativo ir exibir corretamente
atravs de uma variedade de tamanhos de tela do dispositivo. Os tipos de medio
aceitos so definidos no documento Recursos Disponveis.
Posio de Layout
A geometria de uma view a de um retngulo. Uma view tem uma localizao,
expresso como um par de coordenadas esquerda e superior, e duas dimenses, expressa
em uma largura e uma altura. A unidade para a localizao e as dimenses o pixel.
possvel recuperar o local de uma viso chamando os mtodos getLeft() e getTop().
O primeiro retorna a esquerda, ou X, de coordenadas do retngulo que representa o
view. O segundo retorna o topo, ou Y, coordenadas do retngulo que representa o view.
Estes dois mtodos devolvem o local da view em relao ao seu pai. Por exemplo,
quando o Getleft() retorna 20, significa que o ponto de vista est localizado a 20 pixels
para a direita da borda esquerda da sua controladora direta.
Alm disso, vrios mtodos de convenincia so oferecidos para evitar clculos
desnecessrios, ou seja, getRight() e getBottom(). Esses mtodos retornam as
coordenadas das bordas direita e inferior do retngulo que representa o view. Por
exemplo, chamando getRight() semelhante ao seguinte clculo: getLeft() +
getWidth().
Tamanho, padding e margin
O tamanho de uma view expressa com uma largura e uma altura. Uma viso realmente
possue dois pares de valores de largura e altura.
O primeiro par conhecido como largura medida e altura medida. Essas dimenses
definem quo grande quer ser em vista de seu pai. As dimenses medidas podem ser
obtidas chamando getMeasuredWidth() e getMeasuredHeight().
ANDROID, uma viso geral Anderson Duarte de Amorim
123
O segundo par conhecido simplesmente como largura e altura, ou s vezes a largura
de desenho e altura de desenho. Essas dimenses definem o tamanho real do view sobre
tela, em tempo de desenho e depois de layout. Esses valores podem ser, mas no tem
que ser diferentes da largura e altura medidos. A largura e altura podem ser obtidas
chamando getWidth() e getHeight().
Para medir as suas dimenses, uma view leva em conta o seu preenchimento. O
preenchimento expresso em pixels para as partes esquerda, superior, direita e inferior
do view. Padding pode ser utilizado para compensar o contedo da viso de uma
determinada quantidade de pixels. Por exemplo, um padding-left de 2 vai empurrar o
contedo do view por 2 pixels direita da margem esquerda. Padding pode ser definido
usando o mtodo setPadding(int, int, int, int) e consultado chamando getPaddingLeft(),
getPaddingTop(), getPaddingRight() e getPaddingBottom().
Apesar de uma exibio poder definir um padding, isso no prev qualquer apoio para
as margens. No entanto, view groups prestam esse apoio.

ANDROID, uma viso geral Anderson Duarte de Amorim
124
Criando Menus
Os menus so uma parte importante da interface de uma atividade do usurio, que
fornecem aos usurios uma forma familiar para executar aes. Android oferece um
quadro simples para voc adicionar menus padro para seu aplicativo.
Existem trs tipos de menus de aplicao:
Menu de Opes
A coleo de itens do menu principal para uma atividade, que aparece quando o
usurio toca no boto MENU. Quando o aplicativo est rodando o Android 3.0
ou posterior, voc pode fornecer acesso rpido para selecionar itens de menu,
colocando-os diretamente na barra de ao, como "itens de ao."
Menu de Contexto
Uma lista de itens de menu flutuante que aparece quando o usurio toca e tem
uma viso que est registrada para fornecer um menu de contexto.
Submenu
Uma lista de itens de menu flutuante que aparece quando o usurio toca um item
de menu que contm um menu aninhado.
Criando um recurso de menu
Em vez de instanciar um Menu no seu cdigo do aplicativo, voc deve definir um menu
e todos os seus itens em um XML menu resource, em seguida, inflar o recurso de menu
(carreg-lo como um objeto programvel) no seu cdigo do aplicativo. Utilizando um
recurso de menu para definir o seu menu uma boa prtica, pois separa o contedo do
menu de seu cdigo do aplicativo. tambm mais fcil de visualizar a estrutura e o
contedo de um menu em XML.
Para criar um recurso de menu, crie um arquivo XML dentro de seu projeto do diretrio
res/menu/ e crie o menu com os seguintes elementos:

ANDROID, uma viso geral Anderson Duarte de Amorim
125
<menu>
Define um Menu, que um recipiente para itens de menu. Um elemento
<menu> deve ser o n raiz para o arquivo e pode conter um ou mais <item> e
elementos <group>.
<item>
Cria um MenuItem, o que representa um nico item em um menu. Este elemento
pode conter um elemento <menu> aninhado, a fim de criar um submenu.
<group>
Um opcional, recipiente invisvel para elementos <item>. Ele permite que voc
categorize itens de menu para que compartilhe as propriedades tais como estado
ativo e visibilidade.
Aqui est um exemplo de menu chamado game_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/new_game"
android:icon="@drawable/ic_new_game"
android:title="@string/new_game" />
<item android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help" />
</menu>
Este exemplo define um menu com dois itens. Cada item inclui os atributos:
android:id
A identificao do recurso que nico para o item, que permite que o aplicativo
possa reconhecer o item quando o usurio seleciona-o.
android:icon
Uma referncia para um desenho para usar como cone do item.
android:title
Uma referncia a uma string para usar como ttulo do item.
ANDROID, uma viso geral Anderson Duarte de Amorim
126
H muito mais atributos que voc pode incluir em um <item>, incluindo alguns que
especificam como o item pode aparecer na barra de ao.
Inflar um recurso de menu
A partir de seu cdigo de aplicativo, voc pode inflar um recurso de menu (converter o
recurso de XML em um objeto programvel) utilizando MenuInflater.inflate(). Por
exemplo, o seguinte cdigo infla o arquivo game_menu.xml definido acima, durante o
mtodo de retorno onCreateOptionsMenu(), para usar o menu como a atividade do
Menu de Opes:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}
O mtodo getMenuInflater() retorna uma MenuInflater para a atividade. Com este
objetivo, voc pode chamar inflate(),que infla um recurso de menu em um objeto Menu.
Neste exemplo, o recurso de menu definido por game_menu.xml inflado no Menu que
foi passado para onCreateOptionsMenu().
Criando um Menu de Opes
Quando executado em um dispositivo com Android
2.3 e inferior, o Menu de Opes aparece na parte
inferior da tela, como mostrado na figura 1. Quando
aberto, a primeira poro visvel do Menu de Opes
o menu do cone. Ele mantm os seis primeiros itens
do menu. Se voc adicionar mais de seis itens do
Menu de Opes, o Android coloca o sexto item e
aqueles aps no menu de estouro, que o usurio pode
abrir tocando no item "More" do menu.


Figura 1. Screenshot do menu de opes no browser.
ANDROID, uma viso geral Anderson Duarte de Amorim
127
No Android 3.0 e superior, os itens do Menu de Opes so colocados na barra de ao,
que aparece no topo da atividade no lugar da barra de ttulo tradicional. Por padro
todos os itens do Menu de Opes so colocados no menu de estouro, que o usurio
pode abrir ao tocar no cone do menu no lado direito da barra de ao. No entanto, voc
pode colocar itens de menu diretamente na Barra de ao como "itens de ao", para
acesso instantneo, como mostrado na figura 2.

Figura 2. Imagem da barra de ao na aplicao de e-mail, com dois itens de ao do Menu de Opes,
alm do menu de estouro.
Quando o sistema Android cria o Menu de Opes, pela primeira vez, ele chama o
mtodo onCreateOptionsMenu() da sua atividade. Substituir este mtodo em sua
atividade e preencher o Menu que passado para o mtodo, Menu inflando um recurso
de menu como descrito acima em Inflating a Menu Resource. Por exemplo:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}
Voc tambm pode preencher o menu em cdigo, usando add() para adicionar itens ao
Menu.
Nota: No Android 2.3 e inferiores, o sistema chama onCreateOptionsMenu() para criar
o menu de opes quando o usurio abre pela primeira vez, mas no Android 3.0 e
superior, o sistema cria assim que a atividade criada, a fim e preencher a barra de
ao.
Respondendo ao do usurio
Quando o usurio seleciona um item de menu do Menu de Opes (incluindo itens de
ao na barra de ao), o sistema chama o mtodo onOptionsItemSelected() da sua
atividade. Este mtodo passa o MenuItem que o usurio selecionou. Voc pode
identificar o item de menu chamando getItemId(), que retorna o ID nico para o item de
menu (definido pelo atributo android:id no recurso de menu ou com um nmero inteiro
ANDROID, uma viso geral Anderson Duarte de Amorim
128
dado ao mtodo add()). Voc pode combinar esta identificao contra itens do menu
conhecidos e executar a ao apropriada. Por exemplo:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Neste exemplo, getItemId() consulta o ID do item de menu selecionado e o comando
switch compara o ID contra os IDs de recursos que foram atribudos aos itens do menu
no recurso XML. Quando um switch case manipula o item de menu, ela retorna true
para indicar que a seleo de item foi tratada. Caso contrrio, a declarao padro passa
o item de menu para a super classe, no caso dele poder lidar com o item selecionado.
(Se voc diretamente estendeu a classe Activity, ento, a super classe retorna false, mas
uma boa prtica passar itens de menu no tratados para a classe super em vez de
diretamente retornar false).
Alm disso, o Android 3.0 adiciona a capacidade de definir o comportamento de clicar
em um item de menu no menu de recursos XML, usando o atributo android:onClick.
Ento voc no precisa implementar onOptionsItemSelected(). Usando o atributo
android:onClick, voc pode especificar um mtodo a ser chamado quando o usurio
seleciona o item de menu. Sua atividade deve, ento, aplicar o mtodo especificado no
android:onClick para que ele aceite um nico MenuItem de parmetro, quando o
sistema chama este mtodo, ele passa o item de menu selecionado.
Dica: Se seu aplicativo contm atividades mltiplas e algumas delas oferecem o mesmo
Menu de Opes, considere a criao de uma atividade que no executa nada, exceto
os mtodos onCreateOptionsMenu() e onOptionsItemSelected(). Em seguida, estenda
esta classe para cada atividade que deve compartilhar o mesmo menu de opes. Dessa
forma, voc tem que gerenciar apenas um conjunto de cdigo para manipular aes de
menu e cada classe descendente herda o comportamento do menu.
ANDROID, uma viso geral Anderson Duarte de Amorim
129

Se voc quiser adicionar itens de menu para um dos descendentes de suas atividades,
sobreponha onCreateOptionsMenu() nessa atividade. Chame
super.onCreateOptionsMenu(menu) para que os itens do menu inicial sejam criados,
em seguida, adicione novos itens de menu com menu.add(). Voc tambm pode
substituir o comportamento da super classe para os itens de menu individuais.
Alterando os itens de menu em tempo de execuo
Uma vez que a atividade criada, o mtodo onCreateOptionsMenu() chamado apenas
uma vez, como descrito acima. O sistema mantm e re-utiliza o Menu que voc define
neste mtodo at que sua atividade seja destruda. Se voc quiser mudar o menu de
opes a qualquer momento aps ter sido criado pela primeira vez, voc deve substituir
o mtodo onPrepareOptionsMenu(). Isto lhe passa o objeto Menu como ele existe
atualmente. Isso til se voc quiser remover, adicionar, desativar ou ativar itens de
menu, dependendo do estado atual de sua aplicao.
No Android 2.3 e inferiores, o sistema chama onPrepareOptionsMenu() cada vez que o
usurio abre o Menu de Opes.
No Android 3.0 e superior, voc deve chamar invalidateOptionsMenu() quando voc
desejar atualizar o menu, porque o menu est sempre aberto. O sistema ir ento chamar
onPrepareOptionsMenu(), assim voc pode atualizar os itens de menu.
Nota: Voc nunca deve alterar itens no menu de opes com base no View atualmente
em foco. Quando estiver no modo de toque (quando o usurio no estiver usando um
trackball ou d-pad), views podem no ter foco, ento voc nunca deve usar o foco como
base para a modificao de itens do Menu de Opes. Se voc quiser fornecer itens de
menu que so sensveis ao contexto para uma View, use um menu de contexto.
Se voc est desenvolvendo para o Android 3.0 ou superior, no se esquea de ler
tambm Usando a Barra de Ao.
Criando um Menu de Contexto
Um menu de contexto conceitualmente semelhante ao menu exibido quando o usurio
executa um "clique-direito" em um PC. Voc deve usar um menu de contexto para
proporcionar ao usurio o acesso s aes que pertencem a um item especfico na
ANDROID, uma viso geral Anderson Duarte de Amorim
130
interface do usurio. No Android, um menu de contexto exibido quando o usurio
executa um "toque longo" (pressiona e segura) em um item.
Voc pode criar um menu de contexto para qualquer view, apesar de menus de contexto
serem mais freqentemente utilizados para os itens em um ListView. Quando o usurio
pressiona longamente em um item em uma ListView e a lista est registrada para
fornecer um menu de contexto, o item da lista sinaliza para o usurio que um menu de
contexto est disponvel animando sua cor de fundo, que faz a transio do laranja ao
branco antes de abrir o menu de contexto. (O aplicativo Contatos demonstra esta
caracterstica.)
A fim de fornecer um menu de contexto,
voc deve "registrar" a view de um menu
de contexto. Chame
registerForContextMenu() e passe a View
que voc quer dar um menu de contexto.
Quando esta view receber um toque de
longa durao, ela exibe um menu de
contexto.
Para definir a aparncia e comportamento
do menu de contexto, substitua seus
mtodos de retorno do menu de contexto
da atividade, onCreateContextMenu() e onContextItemSelected().
Por exemplo, aqui est um onCreateContextMenu() que usa o recurso de menu
context_menu.xml:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
MenuInflater usado para inflar o menu de contexto de um recurso de menu. (Voc
tambm pode usar o add() para adicionar itens de menu). Os parmetros de mtodo de
retorno incluem o View que o usurio selecionou e ContextMenu.ContextMenuInfo que
Registre uma ListView
Se a sua atividade usa um ListView e voc
deseja que todos os itens da lista forneam
um menu de contexto, registre todos os
itens de um menu de contexto, passando o
ListView para registerForContextMenu().
Por exemplo, se voc estiver usando uma
ListActivity, registre todos os itens da lista
como esta:
registerForContextMenu( getListView() );
ANDROID, uma viso geral Anderson Duarte de Amorim
131
fornece informaes adicionais sobre o item selecionado. Voc pode usar esses
parmetros para determinar qual menu de contexto deve ser criado, mas neste exemplo,
todos os menus de contexto para a atividade so os mesmos.
Ento, quando o usurio seleciona um item no menu de contexto, o sistema chama
onContextItemSelected(). Aqui est um exemplo de como voc pode manipular os itens
selecionados:
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
A estrutura deste cdigo semelhante ao exemplo de criao de um Menu de Opes,
em que getItemId() consulta o ID do item de menu selecionado e um switch
corresponde ao item para as identificaes que so definidos no recurso de menu. E
como o exemplo do menu de opes, a declarao padro chama a super classe no caso
dela poder lidar com itens de menu no tratados aqui, se necessrio.
Neste exemplo, o item selecionado um item da ListView. Para executar uma ao
sobre o item selecionado, o aplicativo precisa saber o ID da lista para o item selecionado
(a sua posio no ListView). Para obter o ID, o aplicativo chama getMenuInfo(), que
retorna um objeto AdapterView.AdapterContextMenuInfo que inclui a identificao de
lista para o item selecionado no campo id. Os mtodos locais editNote() e deleteNote()
aceitam essa identificao da lista para executar uma ao nos dados especificados pelo
ID da lista.
Nota: Os itens em um menu de contexto no suportam cones ou teclas de atalho.

ANDROID, uma viso geral Anderson Duarte de Amorim
132
Criando Submenus
Um submenu um menu que o usurio pode abrir por selecionar um item em outro
menu. Voc pode adicionar um submenu a qualquer menu (com exceo de um
submenu). Submenus so teis quando seu aplicativo tem um monte de funes que
podem ser organizadas em tpicos, como os itens na barra de uma aplicao para PC de
menu (Arquivo, Editar, Exibir, etc.)
Ao criar o seu recurso de menu, voc pode criar um submenu, adicionando um
elemento <menu> como o filho de um <item>. Por exemplo:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/file"
android:icon="@drawable/file"
android:title="@string/file" >
<!-- "file" submenu -->
<menu>
<item android:id="@+id/create_new"
android:title="@string/create_new" />
<item android:id="@+id/open"
android:title="@string/open" />
</menu>
</item>
</menu>
Quando o usurio seleciona um item do submenu, o respectivo mtodo de retorno on-
item-selected do menu pai recebe o evento. Por exemplo, se o menu acima aplicado
como um Menu de Opes, ento o mtodo onOptionsItemSelected() chamado
quando um item de submenu selecionado.
Voc tambm pode usar addSubMenu() para adicionar dinamicamente um SubMenu a
um Menu j existente. Isso retorna o novo objeto SubMenu, para o qual voc pode
adicionar itens de submenu, usando add().
Outras funes do menu
Aqui esto algumas outras caractersticas que podem ser aplicadas a itens do menu.
Grupos de Menu
Um grupo de menu uma coleo de itens de menu que compartilham certas
caractersticas.
ANDROID, uma viso geral Anderson Duarte de Amorim
133
Com um grupo, voc pode:
Mostrar ou ocultar todos os itens com setGroupVisible()
Ativar ou desativar todos os itens com setGroupEnabled()
Especificar se todos os itens so verificados com setGroupCheckable()
Voc pode criar um grupo aninhando elementos <item> dentro de um elemento
<group> em seu recurso de menu ou pela especificao de um ID de grupo com o
mtodo add().
Aqui est um exemplo de recurso de menu que inclui um grupo:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/item1"
android:icon="@drawable/item1"
android:title="@string/item1" />
<!-- menu group -->
<group android:id="@+id/group1">
<item android:id="@+id/groupItem1"
android:title="@string/groupItem1" />
<item android:id="@+id/groupItem2"
android:title="@string/groupItem2" />
</group>
</menu>
Os itens que esto no grupo aparecem da mesma forma que o primeiro item que no est
em um grupo - todos os trs itens no menu so irmos. No entanto, voc pode modificar
as caractersticas dos dois elementos do grupo, referenciando o ID do grupo e utilizando
os mtodos listados acima.
Itens de menu verificados
Um menu pode ser til como uma interface fazendo das opes
ativas e inativas, usando uma caixa de seleo para as opes de
stand-alone, ou radion buttons para grupos com opes mutuamente
exclusivas. A Figura 2 mostra um submenu com os itens que so
verificados com radio buttons.

Figura 3. Screenshot de um submenu com os itens verificados.
ANDROID, uma viso geral Anderson Duarte de Amorim
134

Nota: Os itens de menu no menu de cone (no menu Opes) no podem exibir uma
caixa de seleo ou radio button. Se voc optar por fazer os itens no menu do cone
selecionveis, voc deve manualmente indicar o estado marcado por trocar o cone
e/ou texto cada vez que ocorrem as mudanas de estado.
Voc pode definir o comportamento checkable para itens individuais de menu usando o
atributo android:checkable no elemento <item>, ou para um grupo inteiro com o
atributo android:checkableBehavior no elemento <group>. Por exemplo, todos os itens
deste grupo de menu so verificados com um boto de rdio:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item android:id="@+id/red"
android:title="@string/red" />
<item android:id="@+id/blue"
android:title="@string/blue" />
</group>
</menu>
O atributo android:checkableBehavior aceita tanto:
single
Apenas um item do grupo pode ser verificado (botes de rdio)
all
Todos os itens podem ser verificados (caixas)
none
Nenhum item pode ser verificado
Voc pode aplicar um estado padro verificado de um item usando o atributo
android:checked no elemento <item> e alter-lo em cdigo com o mtodo setChecked().
Quando um item checkable selecionado, o sistema chama o seu mtodo de retorno
item-selected (como onOptionsItemSelected()). aqui que voc deve definir o estado
da caixa, pois um boto de opo ou de rdio no muda o seu estado automaticamente.

ANDROID, uma viso geral Anderson Duarte de Amorim
135
Voc pode consultar o estado atual do item (como era antes que o usurio selecionou)
com isChecked() e, em seguida, definir o estado de verificado com setChecked(). Por
exemplo:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.vibrate:
case R.id.dont_vibrate:
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Se voc no definir o estado de verificado dessa forma, o estado visvel do item (a
caixa de seleo ou boto de rdio) no vai mudar quando o usurio selecion-lo.
Quando voc definir o estado, a atividade preserva o estado de verificado do item para
que quando o usurio abra o menu mais tarde, o estado de verificado que voc definiu
esteja visvel.
Nota: os itens de menu verificveis se destinam a serem usados apenas em uma sesso
base e no sero salvos aps a aplicao ser destruda. Se voc tiver as configuraes
do aplicativo que voc gostaria de salvar para o usurio, voc deve armazenar os
dados usando Preferncias Compartilhadas.
As teclas de atalho
Para facilitar o acesso rpido aos itens do menu de opes quando o dispositivo do
usurio tem um teclado fsico, voc pode adicionar atalhos de acesso rpido usando
letras e/ou nmeros, com os atributos android:alphabeticShortcut e
android:numericShortcut no elemento <item>. Voc tambm pode usar os mtodos
setAlphabeticShortcut(char) e setNumericShortcut(char). Teclas de atalho no so case
sensitive.
Por exemplo, se voc aplicar o caractere "s" como um atalho alfabtico para um item
"salvar" de menu, ento quando o menu est aberto (ou quando o usurio segura o boto
MENU) e o usurio pressiona a tecla "s", o item "Salvar" selecionado.
ANDROID, uma viso geral Anderson Duarte de Amorim
136
Esta tecla de atalho exibida como uma dica no item de menu, abaixo do nome do item
de menu (com exceo de itens no menu do cone, que so exibidas somente se o
usurio segura o boto MENU).
Nota: as teclas de atalho para itens de menu s funcionam em dispositivos com um
teclado de hardware. Atalhos no podem ser adicionado a itens de um menu de
contexto.
Adicionar intenes em menu dinamicamente
s vezes voc quer um item de menu para iniciar uma atividade usando uma Intent (seja
uma atividade em seu aplicativo ou outro aplicativo). Quando voc sabe a inteno que
voc deseja usar e tem um item de menu especfico que deve iniciar a inteno, voc
pode executar a inteno com startActivity() durante o apropriado mtodo de retorno
on-item-selected (como o callback onOptionsItemSelected()).
No entanto, se voc no tiver certeza de que o dispositivo do usurio contm um
aplicativo que lida com a inteno, ento adicionar um item de menu que chama isso
pode resultar em um item de menu que no funciona, porque a inteno pode no
resolver a uma atividade. Para resolver isso, Android permite a voc adicionar
dinamicamente os itens do menu para o menu quando Android encontra atividades
sobre o dispositivo que lidam com sua inteno.
Para adicionar itens de menu baseado em atividades disponveis que aceitam uma
inteno:
1. Definir uma inteno, com a categoria CATEGORY_ALTERNATIVE e/ou
CATEGORY_SELECTED_ALTERNATIVE, alm de quaisquer outras
exigncias.
2. Chamar Menu.addIntentOptions(). Android ento procura todas as aplicaes
que podem executar a inteno e adiciona-os ao seu menu.
Se no houver aplicativos instalados que satisfazem a inteno, ento no h itens de
menu que sejam adicionados.
ANDROID, uma viso geral Anderson Duarte de Amorim
137
Nota: CATEGORY_SELECTED_ALTERNATIVE usada para segurar o elemento
selecionado atualmente na tela. Assim, ele s deve ser utilizado para a criao de um
menu em onCreateContextMenu().
Por exemplo:
@Override
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);

// Create an Intent that describes the requirements to fulfill, to be included
// in our menu. The offering app must include a category value of
Intent.CATEGORY_ALTERNATIVE.
Intent intent = new Intent(null, dataUri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

// Search and populate the menu with acceptable offering applications.
menu.addIntentOptions(
R.id.intent_group, // Menu group to which new items will be added
0, // Unique item ID (none)
0, // Order for the items (none)
this.getComponentName(), // The current activity name
null, // Specific items to place first (none)
intent, // Intent created above that describes our requirements
0, // Additional flags to control items (none)
null); // Array of MenuItems that correlate to specific items (none)

return true;
}
Para cada atividade descoberta que fornece uma inteno de filtro correspondente a
inteno definida um item de menu adicionado, utilizando o valor na inteno do filtro
android:label como o ttulo do item de menu e o cone do aplicativo como o item cone
do menu. O mtodo addIntentOptions() retorna o nmero de itens de menu que foram
acrescentados.
Nota: Quando voc chamar addIntentOptions(), ela substitui qualquer e todos os itens
do menu, o grupo de menu especificado no primeiro argumento.
Permitindo a sua atividade a ser adicionada para outros menus
Voc tambm pode oferecer os servios de sua atividade para outras aplicaes, para
que seu aplicativo possa ser includo no menu de outros (inverter os papis descritos
acima).
ANDROID, uma viso geral Anderson Duarte de Amorim
138
Para ser includo em outros menus de aplicativos, voc precisa definir uma inteno de
filtro, como de costume, mas no se esquea de incluir o
CATEGORY_ALTERNATIVE e/ou CATEGORY_SELECTED_ALTERNATIVE
para o filtro de categoria intenes. Por exemplo:
<intent-filter label="Resize Image">
...
<category android:name="android.intent.category.ALTERNATIVE" />
<category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
...
</intent-filter>
Leia mais sobre como escrever filtros de inteno em Intents and Intents Filters.

ANDROID, uma viso geral Anderson Duarte de Amorim
139
Usando a barra de ao
A barra de ao um widget para atividades que substitui a tradicional barra de ttulo no
topo da tela. Por padro, a barra de ao inclui o logotipo da aplicao do lado
esquerdo, seguido do ttulo da atividade, e todos os itens disponveis no menu Opes
no lado direito. A Barra de ao oferece vrios recursos teis, incluindo a capacidade
de:
Exibir itens do Menu de Opes diretamente na Barra de ao, como "itens de
ao" - fornecendo acesso imediato s aes-chave dos usurios.
Os itens de menu que no aparecem como itens de ao so colocados no menu
de estouro, revelado por uma lista suspensa na barra de aes.
Fornecer as guias para navegar entre os fragmentos.
Fornea uma lista drop-down para a navegao.
Fornecer interativas "vises de ao" no lugar de itens de ao (como uma caixa
de pesquisa).

Figura 1. Uma imagem da barra de ao na aplicao de e-mail, contendo itens de ao para compor
novo email e atualizar a caixa de entrada.
Adicionando a barra de ao
A barra de ao includa por padro em todas as atividades que visam o Android 3.0
ou superior. Mais especificamente, todas as atividades que usam o novo tema
"hologrfico" incluem a barra de ao, e qualquer aplicao que tem como alvo o
Android 3.0 automaticamente recebe esse tema. Uma aplicao considerada para "o
alvo" Android 3.0 quando definido tanto o atributo android:minSdkVersion ou
android:targetSdkVersion no elemento <uses-sdk> para "11" ou superior. Por exemplo:

ANDROID, uma viso geral Anderson Duarte de Amorim
140
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloworld"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4"
android:targetSdkVersion="11" />
<application ... >
...
</application>
</manifest>
Neste exemplo, a aplicao requer uma verso mnima do API Nvel 4 (Android 1.6),
mas tambm atinge API Nvel 11 (Android 3.0). Dessa forma, quando o aplicativo
instalado em um dispositivo rodando Android 3.0 ou superior, o sistema aplica o tema
hologrfico para cada atividade, e assim, cada atividade inclui a Barra de Aes.
No entanto, se voc quiser usar APIs de Barra de Aes, tais como guias para adicionar
ou modificar estilos da barra de ao, voc precisa definir o android:minSdkVersion
para "11", assim voc pode acessar a classe ActionBar.
Removendo a barra de ao
Se voc quiser remover a barra de ao para uma determinada atividade, defina o tema
da atividade para Theme.Holo.NoActionBar. Por exemplo:
<activity android:theme="@android:style/Theme.Holo.NoActionBar">
Dica: Se voc tem um tema de atividade personalizado no qual voc gostaria de
remover a barra de ao, defina a propriedade de estilo android:windowActionBar
false.
Voc tambm pode ocultar a barra de ao em tempo de execuo chamando hide(), e
depois mostr-la novamente chamando show(). Por exemplo:
ActionBar actionBar = getActionBar();
actionBar.hide();
Quando a barra de ao se esconde, o sistema ajusta seu contedo das atividades para
preencher todo o espao disponvel na tela.
Nota: Se voc remover a Barra de ao usando um tema, a janela no vai permitir a
barra de ao a todos, ento voc no pode adicion-la em tempo de execuo -
chamar getActionBar() ir retornar null.
ANDROID, uma viso geral Anderson Duarte de Amorim
141
Adicionando itens de ao
Um item de ao que simplesmente um item do menu de opes que voc declara
deve aparecer diretamente na barra de aes. Um item de ao pode incluir um cone
e/ou texto. Se um item de menu no aparece como um item de ao, o sistema coloca no
menu de estouro, que o usurio pode abrir com o cone do menu no lado direito da barra
de ao.

Figura 2. Uma barra de ao com dois itens de ao e menu de estouro.
Quando a primeira atividade comea, o sistema preenche a barra de ao e menu de
estouro chamando onCreateOptionsMenu() para sua atividade. Conforme discutido no
guia para a criao de menus, neste mtodo callback que voc define o menu de
opes para a atividade.
Voc pode especificar um item de menu para aparecer como um item de ao, se no
houver espao para isso, a partir do seu recurso de menu, declarando
android:showAsAction="ifRoom" para o elemento <item>. Desta forma, o item de
menu aparece na barra de ao para um acesso rpido apenas se houver espao
disponvel para ele. Se no houver espao suficiente, o item colocado no menu de
transbordamento (revelado pelo cone do menu no lado direito da barra de ao).
Voc tambm pode declarar um item de menu para aparecer como um item de ao a
partir do seu cdigo de aplicativo, chamando setShowAsAction() no MenuItem e
passando SHOW_AS_ACTION_IF_ROOM.
Se o item de menu fornece tanto um ttulo como um cone, ento o item de ao mostra
apenas o cone por default. Se voc quiser incluir o texto do item de ao, adicione a
flag "with text": em XML, adicionar withText para o atributo android:showAsAction
ou, no cdigo do aplicativo, use a flag SHOW_AS_ACTION_WITH_TEXT ao chamar
setShowAsAction(). A Figura 2 mostra uma barra de ao que tem dois itens de ao
com o texto e o cone para o menu de estouro.
Aqui est um exemplo de como voc pode declarar um item de menu como um item de
ao em um arquivo de recurso de menu:
ANDROID, uma viso geral Anderson Duarte de Amorim
142
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_add"
android:icon="@drawable/ic_menu_save"
android:title="@string/menu_save"
android:showAsAction="ifRoom|withText" />
</menu>
Neste caso, tanto as flags ifRoom e withText esto definidas, de modo que quando este
item aparece como um item de ao, inclui o texto do ttulo, juntamente com o cone.
Um item de menu colocado na barra de ao dispara os mesmos mtodos de callback
que outros itens do menu de opes. Quando o usurio seleciona um item de ao, sua
atividade recebe uma chamada para onOptionsItemSelected(), passando o ID do item.
Nota: Se voc adicionou o item de menu de um fragmento, o respectivo mtodo
onOptionsItemSelected() chamado para esse fragmento. No entanto, a atividade tem a
chance de manipul-lo primeiro, ento o sistema chama onOptionsItemSelected() da
atividade antes de chamar o fragmento.
Voc tambm pode declarar um item que sempre aparece como um item de ao, mas
voc deve evitar faz-lo, porque ele pode criar uma interface confusa se houver muitos
itens de ao e tambm podem colidir com outros elementos na barra de aes.
Usando o cone do aplicativo como um item de ao
Por padro, o cone do aplicativo aparece na barra de aes, no lado esquerdo. Ele
tambm responde interao do usurio (quando o usurio toca, ele responde
visualmente do mesmo jeito que os itens de ao) e que sua responsabilidade fazer
algo quando o usurio toca-os.

Figura 3. Barra de ao de email, com o cone do aplicativo no lado esquerdo.
O comportamento deve ser normal para a sua aplicao para regressar "HOME"
atividade ou ao estado inicial (como quando a atividade no mudou, mas os fragmentos
foram alterados) quando o usurio toca o cone. Se o usurio j est em casa ou no
estado inicial, ento voc no precisa fazer nada.
ANDROID, uma viso geral Anderson Duarte de Amorim
143
Quando o usurio toca o cone, o sistema chama o mtodo onOptionsItemSelected() de
sua atividade com o ID android.R.id.home. Ento, voc precisa adicionar uma condio
para o seu mtodo onOptionsItemSelected() para receber android.R.id.home e executar
a ao apropriada, como iniciar a atividade inicial ou remover recentes transaes do
fragmento fora da pilha.
Se voc responder para o cone do aplicativo, retornando atividade inicial, voc deve
incluir o flag FLAG_ACTIVITY_CLEAR_TOP na Intent. Com este indicador, se a
atividade que voc est comeando j existe na tarefa atual, ento todas as atividades
em cima dela so destrudas e essa trazida para frente. Voc deve favorecer essa
abordagem, porque ir para "HOME" uma ao que equivalente a "voltar atrs" e
voc geralmente no deve criar uma nova instncia da atividade inicial. Caso contrrio,
voc pode acabar com uma longa pilha de atividades na tarefa atual.
Por exemplo, aqui est uma implementao do onOptionsItemSelected() que retorna
para a aplicao da "HOME" de atividade:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Usando o cone do aplicativo para navegar "para cima"
Voc tambm pode usar o cone do aplicativo para oferecer uma
navegao "para cima" para o usurio. Isto especialmente til
quando o aplicativo composto por atividades que geralmente
aparecem em uma certa ordem e se pretende facilitar a
habilidade do usurio para navegar na hierarquia de atividade.

A maneira como voc responde a este evento a mesma de quando navegando para
HOME (como discutido acima, exceto se voc iniciar uma atividade diferente, com base
ANDROID, uma viso geral Anderson Duarte de Amorim
144
na atividade corrente). Tudo que voc precisa fazer para indicar ao usurio que o
comportamento diferente definir a barra de ao para "mostrar a HOME como para
cima". Voc pode fazer isso chamando setDisplayHomeAsUpEnabled(true) na barra de
aes da sua atividade. Quando o fizer, o sistema retira o cone do aplicativo com uma
seta indicando o comportamento para cima, como mostrado acima.
Por exemplo, aqui est como voc pode mostrar o cone do aplicativo como uma ao
"para cima":
@Override
protected void onStart() {
super.onStart();
ActionBar actionBar = this.getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
Ento, sua atividade deve responder ao usurio tocar no cone, a partir do
onOptionsItemSelected(), recebendo o ID android.R.id.home (como mostrado acima).
Neste caso, ao navegar para cima, ainda mais importante que voc use o
FLAG_ACTIVITY_CLEAR_TOP na Intent, de modo que voc no cria uma nova
instncia da atividade do pai, se j existe um.
Adicionando uma exibio de ao

Figura 5. Uma viso de ao com um widget SearchView.
Uma exibio de ao um widget que aparece na barra de ao como um substituto
para um item de ao. Por exemplo, se voc tem um item no menu opes para "Busca",
voc pode adicionar uma exibio de ao para o item que fornece um widget
SearchView na barra de ao sempre que o item ativado como um item de ao.
Ao adicionar uma viso de ao para um item de menu, importante que voc ainda
permita ao item se comportar como um item de menu normal quando ela no aparece na
barra de aes. Por exemplo, um item de menu para realizar uma pesquisa deve, por
padro, abrir a janela de pesquisa do Android, mas se o item colocado na barra de
ao, a viso de ao aparece com um widget SearchView. A Figura 5 mostra um
exemplo do SearchView em uma viso de ao.
ANDROID, uma viso geral Anderson Duarte de Amorim
145
A melhor forma de declarar uma viso de ao para um item est em seu recurso de
menu, usando o atributo android:actionLayout ou android:actionViewClass:
O valor para android:actionLayout deve ser um ponteiro de recurso para um
arquivo de layout. Por exemplo:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_search"
android:title="Search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="ifRoom"
android:actionLayout="@layout/searchview" />
</menu>
O valor para android:actionViewClass deve ser um nome de classe qualificado
para o View que voc deseja usar. Por exemplo:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_search"
android:title="Search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
Voc deve incluir android:showAsAction="ifRoom" para que o item aparea como uma
viso de ao quando o room est disponvel. Se necessrio, no entanto, pode forar o
item que sempre aparea como uma viso de ao, definindo android:showAsAction
para "always".
Agora, quando o item de menu exibido como um item de ao, esta vista de ao
aparece em vez do cone e/ou texto do ttulo. No entanto, se no houver espao
suficiente na barra de ao, o item aparece no menu de estouro como um item de menu
normal e voc deve responder a ela a partir do mtodo de retorno
onOptionsItemSelected().
Quando a primeira atividade comea, o sistema preenche a barra de ao e menu de
estouro chamando onCreateOptionsMenu(). Depois de ter inflado seu menu neste
mtodo, voc pode adquirir elementos em uma viso de ao (talvez a fim de anexar
ouvintes) chamando findItem() com o ID do item de menu, ento getActionView() no
ANDROID, uma viso geral Anderson Duarte de Amorim
146
MenuItem retornado. Por exemplo, o widget de busca do modelo acima adquirido
como este:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options, menu);
SearchView searchView = (SearchView)
menu.findItem(R.id.menu_search).getActionView();
// Set appropriate listeners for searchView
...
return super.onCreateOptionsMenu(menu);
}
Adicionando abas

Figura 6. Screenshot de abas na barra de ao, do modelo de aplicao do Honeycomb Gallery.
A Barra de ao pode exibir guias que permitem ao usurio navegar entre diferentes
fragmentos na atividade. Cada guia pode incluir um ttulo e/ou um cone.
Para comear, o esquema deve incluir um View, em que cada Fragment associado com
uma guia exibida. Tenha certeza de que tem uma identificao que pode ser usada
para fazer referncia a ela em seu cdigo.
Para adicionar guias para a barra de aes:
1. Criar uma aplicao de ActionBar.TabListener para manipular os eventos de
interao na barra de guias de ao. Voc deve implementar todos os mtodos:
onTabSelected(), onTabUnselected(), e onTabReselected().
Cada mtodo de retorno passa a ActionBar.Tab que recebeu o evento e um
FragmentTransaction para voc efetuar as transaes do fragmento (adicionar ou
remover fragmentos).

ANDROID, uma viso geral Anderson Duarte de Amorim
147
Por exemplo:
private class MyTabListener implements ActionBar.TabListener {
private TabContentFragment mFragment;

// Called to create an instance of the listener when adding a new tab
public TabListener(TabContentFragment fragment) {
mFragment = fragment;
}

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.add(R.id.fragment_content, mFragment, null);
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
ft.remove(mFragment);
}

@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// do nothing
}

}
Esta implementao de ActionBar.TabListener adiciona um construtor que salva
o Fragment associado com um guia para que cada retorno possa adicionar ou
remover esse fragmento.
2. Receba a ActionBar para a sua atividade, chamando getActionBar() de sua
atividade, durante onCreate() (mas no se esquea de fazer isso depois de voc
ter chamado setContentView()).
3. Chame setNavigationMode(NAVIGATION_MODE_TABS) para habilitar o
modo guia para a ActionBar .
4. Criar cada guia para a barra de ao:
a. Criar uma nova ActionBar.Tab chamando newTab() na ActionBar .
b. Acrescentar o texto do ttulo e/ou um cone para o guia, chamando
setText() e/ou setIcon().
Dica: Esses mtodos retornam a mesma instncia ActionBar.Tab, assim
voc pode encadear as chamadas juntas.
ANDROID, uma viso geral Anderson Duarte de Amorim
148
c. Declare o ActionBar.TabListener para usar a guia por meio de um
exemplo de sua aplicao para setTabListener().
5. Adicione cada ActionBar.Tab barra de ao, chamando addTab() na ActionBar
e passe a ActionBar.Tab.
Por exemplo, o cdigo a seguir combina as etapas 2-5 para criar duas guias e adicion-
las Barra de ao:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// setup Action Bar for tabs
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// remove the activity title to make space for tabs
actionBar.setDisplayShowTitleEnabled(false);

// instantiate fragment for the tab
Fragment artistsFragment = new ArtistsFragment();
// add a new tab and set its title text and tab listener
actionBar.addTab(actionBar.newTab().setText(R.string.tab_artists)
.setTabListener(new TabListener(artistsFragment)));

Fragment albumsFragment = new AlbumsFragment();
actionBar.addTab(actionBar.newTab().setText(R.string.tab_albums)
.setTabListener(new TabListener(albumsFragment)));
}
Todos os comportamentos que ocorrem quando uma guia selecionada devem ser
definidos pelo seu mtodo de callback ActionBar.TabListener. Quando uma guia
selecionada, ela recebe uma chamada para onTabSelected() e a que voc deve
adicionar o fragmento apropriado para a exibio designada em seu layout, utilizando
add() com o previsto FragmentTransaction. Da mesma forma, quando uma guia
desmarcada (porque outra guia selecionada), voc deve remover o fragmento do
layout, utilizando remove().
Ateno: Voc no deve chamar commit() para essas operaes, o sistema chama-o
para voc e pode lanar uma exceo se voc cham-lo. Voc tambm no pode
adicionar essas transaes de fragmento para o fundo da pilha.
Se a sua atividade interrompida, voc deve manter a guia selecionada no momento
com o estado salvo de modo que quando o usurio retorna sua aplicao, voc pode
ANDROID, uma viso geral Anderson Duarte de Amorim
149
abrir a guia. Quando hora de salvar o estado, voc pode consultar a atual guia
selecionada com getSelectedNavigationIndex(). Isso retorna a posio do ndice da guia
selecionada.
Ateno: importante que voc salve o estado de cada fragmento quando necessrio,
pois quando o usurio alterna fragmentos com as guias, e em seguida, retorna a um
fragmento anterior, aparece o caminho que ele deixou. Para obter informaes sobre
como salvar o seu estado de fragmento, consulte o guia do desenvolvedor sobre
Fragmentos.
Adicionando de navegao drop-down
Como um outro modo de navegao em sua atividade, voc pode fornecer uma lista
suspensa na barra de aes. Por exemplo, a lista drop-down pode fornecer os meios
alternativos para classificar o contedo da atividade ou mudar a conta do usurio.
Aqui est uma lista rpida de medidas para permitir a navegao drop-down:
1. Criar um SpinnerAdapter que fornece a lista de itens selecionveis para o drop-
down e a disposio para usar ao desenhar cada item na lista.
2. Implementar ActionBar.OnNavigationListener para definir o comportamento
quando o usurio seleciona um item da lista.
3. Habilitar o modo de navegao para a barra de ao com setNavigationMode().
Por exemplo:
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
Nota: Voc deve executar isto durante a sua atividade do mtodo onCreate().
4. Em seguida, defina o retorno para a lista drop-down com
setListNavigationCallbacks(). Por exemplo:
actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
Este mtodo tem a sua SpinnerAdapter e ActionBar.OnNavigationListener.
Essa a configurao bsica. No entanto, a implementao da SpinnerAdapter e
ActionBar.OnNavigationListener onde a maioria do trabalho feito. H muitas
ANDROID, uma viso geral Anderson Duarte de Amorim
150
maneiras que voc pode aplicar isto para definir a funcionalidade para o seu drop-down
de navegao e implementar vrios tipos de SpinnerAdapter alm do escopo deste
documento (voc deve referenciar para a classe SpinnerAdapter para obter mais
informaes). No entanto, abaixo h um exemplo simples para um SpinnerAdapter e
ActionBar.OnNavigationListener para voc comear.
Exemplo de SpinnerAdapter e OnNavigationListener
SpinnerAdapter um adaptador que fornece dados para um widget spinner, como a lista
drop-down na barra de aes. SpinnerAdapter uma interface que voc pode
implementar, mas Android inclui algumas implementaes teis que voc pode
estender, como ArrayAdapter e SimpleCursorAdapter. Por exemplo, aqui est uma
maneira fcil de criar um SpinnerAdapter usando a implementao de ArrayAdapter,
que usa uma matriz de string como fonte de dados:
SpinnerAdapter mSpinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.action_list, android.R.layout.simple_spinner_dropdown_item);
O mtodo createFromResource() usa trs parmetros: a aplicao Context, a
identificao de recursos para array de string, e o layout a ser usado para cada item da
lista.
Um array de string definido em um recurso parecido com este:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="action_list">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
</string-array>
</pre>
O ArrayAdapter retornado por createFromResource() est completo e pronto para voc
passar a setListNavigationCallbacks() (na etapa 4 acima). Antes de fazer, porm, voc
precisa criar o OnNavigationListener.
A implementao do ActionBar.OnNavigationListener onde voc lida com as
mudanas de fragmento ou outras modificaes sua atividade quando o usurio
seleciona um item da lista drop-down. H apenas um mtodo callback para implementar
o receptor: onNavigationItemSelected().
ANDROID, uma viso geral Anderson Duarte de Amorim
151
O mtodo onNavigationItemSelected() recebe a posio do item na lista e um ID de
nico item fornecido pela SpinnerAdapter.
Aqui est um exemplo que instancia uma implementao annima de
OnNavigationListener, que insere um Fragment dentro do recipiente layout identificado
por R.id.fragment_container:
mOnNavigationListener = new OnNavigationListener() {
// Get the same strings provided for the drop-down's ArrayAdapter
String[] strings = getResources().getStringArray(R.array.action_list);

@Override
public boolean onNavigationItemSelected(int position, long itemId) {
// Create new fragment from our own Fragment class
ListContentFragment newFragment = new ListContentFragment();
FragmentTransaction ft = openFragmentTransaction();
// Replace whatever is in the fragment container with this fragment
// and give the fragment a tag name equal to the string at the position selected
ft.replace(R.id.fragment_container, newFragment, strings[position]);
// Apply changes
ft.commit();
return true;
}
};
Esta instncia de OnNavigationListener est completo e agora voc pode chamar
setListNavigationCallbacks() (na etapa 4), passando o ArrayAdapter e este
OnNavigationListener.
Neste exemplo, quando o usurio seleciona um item da lista drop-down, um fragmento
adicionado ao layout (que substitui o fragmento atual no R.id.fragment_container
vista). O fragmento adicional dada uma etiqueta que identifica-lo, que a mesma
seqncia de caracteres usado para identificar o fragmento na lista drop-down.

ANDROID, uma viso geral Anderson Duarte de Amorim
152
Aqui est um olhar da classe ListContentFragment que define cada fragmento neste
exemplo:
public class ListContentFragment extends Fragment {
private String mText;

@Override
public void onAttach(Activity activity) {
// This is the first callback received; here we can set the text for
// the fragment as defined by the tag specified during the fragment transaction
super.onAttach(activity);
mText = getTag();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// This is called to define the layout for the fragment;
// we just create a TextView and set its text to be the fragment tag
TextView text = new TextView(getActivity());
text.setText(mText);
return text;
}
}
Estilizando a barra de ao
A barra de ao o ttulo do seu aplicativo e um ponto de interao primrio para os
usurios, ento voc pode querer modificar alguns em seu projeto, a fim de torn-lo
sentir mais integrado com o design do aplicativo. H vrias maneiras que voc pode
fazer isso se quiser.
Para modificaes simples para o ActionBar, voc pode usar os mtodos a seguir:
setBackgroundDrawable()
Define um drawable para usar como fundo da barra de ao. O drawable deve
ser uma imagem Nine-patch, uma forma, ou uma cor slida, para que o sistema
pode redimensionar a drawable com base no tamanho da barra de ao (voc no
deve usar uma imagem bitmap de tamanho fixo).
setDisplayUseLogoEnabled()
Permite o uso de uma imagem alternativa (a "logo") na barra de ao, em vez do
cone do aplicativo padro. Um logotipo muitas vezes uma imagem mais
ampla, mais detalhada que representa a aplicao. Quando isso estiver ativado, o
ANDROID, uma viso geral Anderson Duarte de Amorim
153
sistema utiliza a imagem do logotipo definido para a aplicao (ou a atividade
individual) no arquivo de manifesto, com o atributo android:logo. O logotipo
ser redimensionado, conforme necessrio para ajustar a altura da barra de ao.
(Melhores prticas projetar o logotipo com o mesmo tamanho do cone do
aplicativo.)
Para personalizaes mais complexas, voc pode usar estilos e temas do Android para
remodelar sua barra de ao de vrias maneiras.
A Barra de ao tem dois temas padro, "dark" e "light". O tema escuro aplicado com
o tema padro hologrfico, conforme especificado pelo tema Theme.Holo. Se voc
quiser um fundo branco com texto escuro, em vez disso, voc pode aplicar o tema
Theme.Holo.Light para a atividade no arquivo de manifesto. Por exemplo:
<activity android:name=".ExampleActivity"
android:theme="@android:style/Theme.Holo.Light" />
Para ter mais controle, voc pode substituir o tema Theme.Holo ou Theme.Holo.Light e
aplicar estilos personalizados para determinados aspectos da Barra de Aes. Algumas
das propriedades da barra de ao voc pode personalizar incluindo o seguinte:
android:actionBarTabStyle
Estilo de abas na barra de ao.
android:actionBarTabBarStyle
Estilo para a barra que aparece abaixo das abas na barra de ao.
android:actionBarTabTextStyle
Estilo para o texto nos separadores.
android:actionDropDownStyle
Estilo para a lista drop-down utilizado para o menu de navegao de
transbordamento e drop-down.
android:actionButtonStyle
Estilo para a imagem de fundo usado para os botes na barra de ao.
ANDROID, uma viso geral Anderson Duarte de Amorim
154
Por exemplo, aqui est um arquivo de recurso que define um tema personalizado para a
barra de ao, baseado no tema padro Theme.Holo:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBar" parent="android:style/Theme.Holo.Light">
<item
name="android:actionBarTabTextStyle">@style/customActionBarTabTextStyle</item>
<item name="android:actionBarTabStyle">@style/customActionBarTabStyle</item>
<item
name="android:actionBarTabBarStyle">@style/customActionBarTabBarStyle</item>
</style>

<!-- style for the tab text -->
<style name="customActionBarTabTextStyle">
<item name="android:textColor">#2966c2</item>
<item name="android:textSize">20sp</item>
<item name="android:typeface">sans</item>
</style>

<!-- style for the tabs -->
<style name="customActionBarTabStyle">
<item name="android:background">@drawable/actionbar_tab_bg</item>
<item name="android:paddingLeft">20dp</item>
<item name="android:paddingRight">20dp</item>
</style>

<!-- style for the tab bar -->
<style name="customActionBarTabBarStyle">
<item name="android:background">@drawable/actionbar_tab_bar</item>
</style>
</resources>
Nota: Para que a imagem de fundo guia mude, dependendo do estado de separador
atual (selecionado, pressionado, no selecionado), o recurso drawable utilizado deve
ser uma lista de estado drawable. Tambm certo que o tema declara um tema
principal, da qual ele herda todos os estilos no explicitamente declarados em seu
tema.
Voc pode aplicar o seu tema personalizado para o aplicativo inteiro ou para atividades
individuais no arquivo de manifesto, como este:
<application android:theme="@style/CustomActionBar"
... />
Alm disso, se voc quer criar um tema personalizado para a sua atividade que remove a
barra de ao completamente, use os atributos de estilo a seguir:
ANDROID, uma viso geral Anderson Duarte de Amorim
155
android:windowActionBar
Defina esta propriedade de estilo como false para remover a barra de aes.
android:windowNoTitle
Defina esta propriedade de estilo como true tambm para remover a barra de
ttulo tradicional.

ANDROID, uma viso geral Anderson Duarte de Amorim
156
Criando caixas de dilogo
Uma caixa de dilogo geralmente uma pequena janela que aparece na frente da
atividade atual. A atividade em causa perde o foco e o dilogo aceita todas as interaes
do usurio. Os dilogos so normalmente utilizados para as notificaes que devem
interromper o usurio e para executar tarefas curtas que se relacionam diretamente com
a aplicao em curso (como uma barra de progresso ou um prompt de login).
A classe Dialog a classe base para a criao de dilogos. No entanto, voc geralmente
no deve instanciar um Dialog diretamente. Em vez disso, voc deve usar uma das
seguintes subclasses:
AlertDialog
Uma caixa de dilogo que pode gerenciar zero, um, dois ou trs botes, e/ou
uma lista de itens selecionveis que podem incluir caixas de verificao ou
botes de rdio. O AlertDialog capaz de construir a maioria das interfaces de
dilogo com o usurio e o tipo de caixa de dilogo sugerido.
ProgressDialog
Uma caixa de dilogo que exibe uma roda de progresso ou barra de progresso.
Porque uma extenso do AlertDialog, ele tambm suporta botes.
DatePickerDialog
Um dilogo que permite que o usurio selecione uma data.
TimePickerDialog
Um dilogo que permite ao usurio selecionar um tempo.
Se voc quiser personalizar a sua prpria caixa de dilogo, voc pode estender a base
Dialog ou qualquer objeto das subclasses acima e definir um novo layout.
Mostrando uma caixa de dilogo
Um dilogo sempre criado e exibido como parte de uma Activity. Voc normalmente
deve criar dilogos de dentro do mtodo de retorno onCreateDialog(int) da sua
atividade. Quando voc usa esta chamada, o sistema Android gerencia automaticamente
ANDROID, uma viso geral Anderson Duarte de Amorim
157
o estado de cada dilogo e os ganchos para a atividade, efetivamente tornando-o o
"dono" de cada dilogo. Como tal, cada dilogo herda algumas propriedades da
atividade. Por exemplo, quando uma janela aberta, a tecla Menu revela o menu de
opes definidas para a atividade e as teclas de volume modificam o fluxo de udio
usado pela atividade.
Nota: Se voc decidir criar um dilogo fora do mtodo onCreateDialog(), no ir ser
anexado a uma atividade. Voc pode, entretanto, anex-lo a uma atividade com
setOwnerActivity(Activity).
Quando voc quer mostrar uma janela, chame showDialog(int) e passe um nmero
inteiro que identifica a caixa de dilogo que voc deseja exibir.
Quando uma janela solicitada pela primeira vez, o Android chama
onCreateDialog(int) de sua atividade, que onde voc deve criar uma instncia do
Dialog. Neste mtodo de retorno passado o mesmo ID que voc passou para
showDialog(int). Depois de criar o dilogo, retorne o objeto no final do mtodo.
Antes que o dilogo ser exibido, o Android tambm chama o mtodo callback opcional
onPrepareDialog(int, Dialog). Defina nesse mtodo se voc deseja alterar as
propriedades da caixa de dilogo cada vez que for aberta. Este mtodo chamado toda
vez que uma caixa de dilogo aberta, enquanto onCreateDialog(int) chamado apenas
na primeira vez que uma caixa de dilogo aberta. Se voc no definir
onPrepareDialog(), ento o dilogo continuar a ser o mesmo que era o tempo anterior
que foi aberto. Este mtodo tambm passa o ID do dilogo, alm de um dilogo do
objeto que voc criou na onCreateDialog().
A melhor maneira de definir os mtodos de retorno onCreateDialog(int) e
onPrepareDialog(int, Dialog) com uma instruo switch que verifica o parmetro id
que passado para o mtodo. Cada caso deve verificar se h uma identificao nica de
dilogo e, em seguida, criar e definir o respectivo dilogo. Por exemplo, imagine um
jogo que usa dois dilogos distintos: um para indicar que o jogo tem uma pausa e outra
para indicar que o jogo acabou. Primeiro, defina um ID de nmero inteiro para cada
caixa de dilogo:
static final int DIALOG_PAUSED_ID = 0;
static final int DIALOG_GAMEOVER_ID = 1;
ANDROID, uma viso geral Anderson Duarte de Amorim
158
Em seguida, defina a chamada onCreateDialog(int) com um caso de interruptor para
cada ID:
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case DIALOG_PAUSED_ID:
// do the work to define the pause Dialog
break;
case DIALOG_GAMEOVER_ID:
// do the work to define the game over Dialog
break;
default:
dialog = null;
}
return dialog;
}
Nota: Neste exemplo, no h nenhum cdigo dentro da declarao de caso, porque o
procedimento para a definio de seu dilogo est fora do escopo desta seo.
Quando hora de mostrar um dos dilogos, chame showDialog(int) com o ID de um
dilogo:
showDialog(DIALOG_PAUSED_ID);
Dispensar um dilogo
Quando estiver pronto para fechar o dilogo, voc pode descart-lo chamando dismiss()
no objeto Dialog. Se necessrio, voc tambm pode chamar dismissDialog(int) da
atividade, o que efetivamente chama dismiss() na caixa de dilogo para voc.
Se voc estiver usando onCreateDialog(int) para gerir o seu estado de dilogos (como
discutido na seo anterior), ento cada vez que o dilogo indeferido, o estado do
objeto de dilogo mantido pela atividade. Se voc decidir que voc no precisa mais
desse objeto ou importante que o estado esteja limpo, ento voc deve chamar
removeDialog(int). Isto ir remover todas as referncias internas ao objeto e se o
dilogo est mostrando, vai dispens-lo.
Usando demisso de receptores
Se voc quiser que seu aplicativo execute alguns procedimentos no momento em que
um dilogo dispensado, ento voc deve anexar um receptor on-dismiss no seu
dilogo.
ANDROID, uma viso geral Anderson Duarte de Amorim
159
Primeiro defina a interface DialogInterface.OnDismissListener. Essa interface possui
apenas um mtodo, onDismiss(DialogInterface), que ser chamado quando o dilogo
for descartado. Depois, passe a sua implementao OnDismissListener para
setOnDismissListener().
No entanto, note que os dilogos tambm podem estar "cancelados". Este um caso
especial que indica que o dilogo foi explicitamente cancelado por parte do usurio.
Isso ocorrer se o usurio pressiona o boto "BACK " para fechar a janela, ou se a caixa
de dilogo solicita explicitamente cancel() (talvez a partir de um boto "Cancelar" na
caixa de dilogo). Quando um dilogo for cancelado, o OnDismissListener ainda ser
notificado, mas se voc gostaria de ser informado de que o dilogo foi expressamente
cancelado (e no dispensado normalmente), ento voc deve registrar um
DialogInterface.OnCancelListener com setOnCancelListener().
Criando um AlertDialog
Um AlertDialog uma extenso da classe Dialog. capaz de construir a maioria das
interfaces de usurio de dilogo e o tipo de dilogo sugerido. Voc deve us-lo para o
dilogo que usam qualquer uma das seguintes caractersticas:
Um ttulo
Uma mensagem de texto
Um, dois ou trs botes
Uma lista de itens selecionveis (com checkbox ou radio-button)
Para criar um AlertDialog, use a subclasse AlertDialog.Builder. Receba um construtor
com AlertDialog.Builder(Context) e depois use os mtodos pblicos de classe para
definir todas as propriedades AlertDialog. Depois que est finalizado com o construtor,
recupere o objeto AlertDialog com create().
Os tpicos a seguir mostram como definir vrias propriedades do AlertDialog usando a
classe AlertDialog.Builder. Se voc usar qualquer um dos seguintes cdigos de exemplo
dentro do seu mtodo de retorno onCreateDialog(), voc pode retornar o objeto
resultante de dilogo para exibir o dilogo.
ANDROID, uma viso geral Anderson Duarte de Amorim
160
Adicionando botes

Para criar um AlertDialog com botes lado a lado, como a mostrada na imagem
direita, use o mtodo set...Button():
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
MyActivity.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
Primeiro, adicione uma mensagem para o dilogo com setMessage(CharSequence) .
Ento, comece mtodo de encadeamento e definir a janela para no ser cancelado (por
isso o usurio no poder fechar o dilogo com o boto traseiro) com
setCancelable(boolean) . Para cada boto, use um dos set...Button() mtodos, como
setPositiveButton() , que aceita o nome do boto e um DialogInterface.OnClickListener
que define as medidas a tomar quando o usurio seleciona o boto.
Nota: Voc s pode adicionar um boto de cada tipo AlertDialog. Ou seja, voc no
pode ter mais de um boto "positivo". Isso limita o nmero de botes possveis para
trs: positivo, neutro e negativo. Estes nomes so tecnicamente irrelevantes para a
funcionalidade real de seus botes, mas deve ajud-lo a acompanhar o que faz o qu.

ANDROID, uma viso geral Anderson Duarte de Amorim
161
Adicionando uma lista

Para criar um AlertDialog com uma lista de itens selecionveis como o mostrado
esquerda, use o mtodo setItems():
final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
Primeiro, adicione um ttulo para o dilogo com setTitle(CharSequence). Em seguida,
adicione uma lista de itens selecionveis com setItems(), que aceita um conjunto de
itens a serem exibidos e um DialogInterface.OnClickListener que define as medidas a
tomar quando o usurio seleciona um item.
Adicionando caixas de seleo e botes de rdio
Para criar uma lista de itens de escolha mltipla
(caixas) ou itens de escolha nica (botes de rdio)
dentro do dilogo, use os mtodos
setMultiChoiceItems() e setSingleChoiceItems(),
respectivamente. Se voc criar uma destas listas
selecionveis no mtodo de retorno onCreateDialog(),
o Android gerencia o estado da lista para voc.
Contanto que a atividade esteja ativa, o dilogo se lembra dos itens que foram
previamente selecionados, mas quando o usurio sai da atividade, a seleo est
perdida.
ANDROID, uma viso geral Anderson Duarte de Amorim
162
Nota: Para salvar a seleo quando o usurio deixa ou faz pausa na atividade, voc
deve salvar e restaurar corretamente a configurao de todo o ciclo de vida de
atividade. Para salvar permanentemente as selees, mesmo quando o processo de
atividade completamente parado, voc precisa salvar as configuraes com uma das
tcnicas de Armazenamento de Dados.
Para criar um AlertDialog com uma lista de itens de escolha simples, como a mostrada
acima, use o mesmo cdigo do exemplo anterior, mas substitua o mtodo setItems()
pelo setSingleChoiceItems():
final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pick a color");
builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
O segundo parmetro no mtodo setSingleChoiceItems() um valor inteiro para o
checkedItem, que indica a posio de lista com base zero do item selecionado padro.
Use "-1" para indicar que nenhum item deve ser selecionado por padro.
Criar um ProgressDialog
A ProgressDialog uma extenso da classe
AlertDialog que pode exibir uma animao de
progresso na forma de uma roda, para uma tarefa com
o progresso indefinido, ou uma barra de progresso,
para uma tarefa que tem uma progresso definida. O dilogo tambm pode fornecer
botes, como um de cancelar um download.
Abrir uma janela de progresso pode ser to simples como chamar
ProgressDialog.show(). Por exemplo, o dilogo mostrado acima pode ser facilmente
alcanado sem gerenciar o dilogo atravs da chamada onCreateDialog(int), conforme
mostrado abaixo:
ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",
"Loading. Please wait...", true);
ANDROID, uma viso geral Anderson Duarte de Amorim
163
O primeiro parmetro a aplicao Context, o segundo um ttulo para o dilogo
(vazio), o terceiro a mensagem e o ltimo parmetro se o progresso indeterminado
(isso s relevante quando cria uma barra de progresso, que discutido na prxima
seo).
O estilo padro de um dilogo de progresso a roda. Se voc deseja criar uma barra de
progresso que mostra o progresso do carregamento com granularidade, mais cdigo
necessrio, como ser discutido na prxima seo.
Mostrando uma barra de progresso

Para mostrar a progresso com uma barra de progresso animada:
1. Inicialize o ProgressDialog com o construtor da classe,
ProgressDialog(Context).
2. Defina o estilo de progressos para "STYLE_HORIZONTAL" com
setProgressStyle(int) e defina as outras propriedades, como a mensagem.
3. Quando estiver pronto para mostrar o dilogo, chame show() ou devolva o
ProgressDialog do onCreateDialog(int) de retorno.
4. Voc pode incrementar a quantidade de progresso exibida na barra chamando
tanto setProgress(int) com um valor para a porcentagem total concluda ou
incrementProgressBy(int) com um valor incremental para adicionar
porcentagem total concluda at agora.
Por exemplo, sua configurao pode se parecer como esta:
ProgressDialog progressDialog;
progressDialog = new ProgressDialog(mContext);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
ANDROID, uma viso geral Anderson Duarte de Amorim
164
A configurao simples. A maior parte do cdigo necessrio para criar um dilogo de
progresso est realmente envolvida no processo que atualiz-lo. Voc pode achar que
necessrio criar um segundo thread em sua aplicao para este trabalho e, em seguida,
relatar o progresso de volta atividade do thread de interface do usurio com um
Handler do objeto. Se voc no est familiarizado com o uso de threads adicionais com
um manipulador, vejo o exemplo abaixo, que utiliza um segundo thread para
incrementar um dilogo de progresso gerido pela atividade.
Exemplo ProgressDialog com um segundo thread
Este exemplo usa um segundo thread para acompanhar o andamento de um processo
(que na verdade s conta at 100). O thread envia uma Message de volta atividade
principal atravs de um Handler a cada hora em que algum progresso feito. A
atividade principal, em seguida, atualiza o ProgressDialog.
package com.example.progressdialog;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class NotificationTest extends Activity {
static final int PROGRESS_DIALOG = 0;
Button button;
ProgressThread progressThread;
ProgressDialog progressDialog;

/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Setup the button that starts the progress dialog
button = (Button) findViewById(R.id.progressDialog);
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
showDialog(PROGRESS_DIALOG);
}
});
}

protected Dialog onCreateDialog(int id) {
ANDROID, uma viso geral Anderson Duarte de Amorim
165
switch(id) {
case PROGRESS_DIALOG:
progressDialog = new ProgressDialog(NotificationTest.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Loading...");
return progressDialog;
default:
return null;
}
}

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
switch(id) {
case PROGRESS_DIALOG:
progressDialog.setProgress(0);
progressThread = new ProgressThread(handler);
progressThread.start();
}

// Define the Handler that receives messages from the thread and update the progress
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
int total = msg.arg1;
progressDialog.setProgress(total);
if (total >= 100){
dismissDialog(PROGRESS_DIALOG);
progressThread.setState(ProgressThread.STATE_DONE);
}
}
};

/** Nested class that performs progress calculations (counting) */
private class ProgressThread extends Thread {
Handler mHandler;
final static int STATE_DONE = 0;
final static int STATE_RUNNING = 1;
int mState;
int total;

ProgressThread(Handler h) {
mHandler = h;
}

public void run() {
mState = STATE_RUNNING;
total = 0;
while (mState == STATE_RUNNING) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread Interrupted");
}
Message msg = mHandler.obtainMessage();
msg.arg1 = total;
ANDROID, uma viso geral Anderson Duarte de Amorim
166
mHandler.sendMessage(msg);
total++;
}
}

/* sets the current state for the thread,
* used to stop the thread */
public void setState(int state) {
mState = state;
}
}
}
Criando uma caixa de dilogo personalizada
Se voc quiser um projeto personalizado para um
dilogo, voc pode criar seu prprio layout para a
janela de dilogo com elementos de layout e de
widget. Depois de definido o layout, passar o objeto
View raiz ou identificao do recurso de layout para setContentView(View).
Por exemplo, para criar o dilogo mostrado acima:
1. Criar um layout XML salvo como custom_dialog.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
</LinearLayout>
Esta XML define um ImageView e um TextView dentro de um LinearLayout.
2. Definir o layout acima como o contedo da View da caixa de dilogo e definir o
contedo dos elementos ImageView e TextView:
ANDROID, uma viso geral Anderson Duarte de Amorim
167
Context mContext = getApplicationContext();
Dialog dialog = new Dialog(mContext);

dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");

TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
Depois de instanciar o dilogo, definir o layout personalizado de contedo como
contedo da View da caixa de dilogo com setContentView(int), passando o ID
do recurso de layout. Agora que o dilogo tem um layout definido, voc pode
capturar objetos View do layout com findViewById(int) e modificar seu
contedo.
3. isso a. Agora voc pode mostrar o dilogo como descrito em Mostrando um
Dilogo.
Um dilogo feito com a classe de dilogo base deve ter um ttulo. Se voc no chamar
setTitle(), o espao usado para o ttulo continua vazio, mas ainda visvel. Se voc no
quer um ttulo a todos, ento voc deve criar o seu dilogo personalizado usando a
classe AlertDialog. No entanto, porque um AlertDialog mais fcilmente criado com o
AlertDialog.Builder, voc no tem acesso ao mtodo setContentView(int) utilizado
acima. Em vez disso, voc deve usar setView(View). Este mtodo aceita um objeto
View, por isso necessrio inflar o layout do objeto View da raiz do XML.
Para inflar o layout XML, recuperar o LayoutInflater com getLayoutInflater() (ou
getSystemService()), e depois chamar inflate(int, ViewGroup), onde o primeiro
parmetro o ID do recurso layout e o segundo a identificao da View raiz. Neste
ponto, voc pode usar o layout inflado para encontrar objetos View no layout e definir o
contedo dos elementos ImageView e TextView. Ento instanciar o
AlertDialog.Builder e definir o layout inflados para o dilogo com setView(View).
Aqui est um exemplo, criando um layout personalizado em um AlertDialog:
AlertDialog.Builder builder;
AlertDialog alertDialog;

Context mContext = getApplicationContext();
LayoutInflater inflater = (LayoutInflater)
ANDROID, uma viso geral Anderson Duarte de Amorim
168
mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog,
(ViewGroup) findViewById(R.id.layout_root));

TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);

builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
Usando um AlertDialog para o seu layout personalizado permite-lhe tirar partido das
funcionalidades incorporadas AlertDialog como botes geridos, listas selecionveis, um
ttulo, um cone e assim por diante.
ANDROID, uma viso geral Anderson Duarte de Amorim
169
Manipulando eventos de UI
No Android, h mais de um caminho para interceptar os eventos de interao do usurio
com seu aplicativo. Ao considerar os eventos dentro de sua interface de usurio, a
abordagem consiste em capturar os eventos do objeto View especfico com que o
usurio interage. A classe View fornece os meios para faz-lo.
Entre as diversas classes View que voc usar para compor seu layout, voc pode
observar vrios mtodos de retorno pblicos que paream teis para eventos de UI.
Esses mtodos so chamados pelo framework Android, quando a respectiva ao ocorre
no objeto. Por exemplo, quando uma exibio (como um boto) tocada, o mtodo
onTouchEvent() chamado no objeto. No entanto, a fim de interceptar isso, voc deve
estender a classe e substituir o mtodo. No entanto, estender cada objeto View, a fim de
lidar com um evento como esse no seria prtico. por isso que a classe View tambm
contm uma coleo de interfaces aninhadas com callbacks que podem ser muito mais
fcil de definir. Essas interfaces, chamadas de event listeners, so o seu bilhete para
capturar a interao do usurio com sua interface do usurio.
Enquanto voc vai utilizar mais comumente os ouvintes de evento para receber a
interao do usurio, pode chegar um momento em que voc quer estender uma classe,
no intuito de construir um componente personalizado. Talvez voc queira estender a
classe Button para fazer algo mais extravagante. Neste caso, voc ser capaz de definir
o comportamento de eventos padro para sua classe usando a classe de manipuladores
de eventos.
Os ouvintes de eventos
Um receptor de evento uma interface na classe View que contm um mtodo de
retorno nico. Esses mtodos sero chamados pelo framework Android quando o View
para o receptor tenha sido registado desencadeada pela interao do usurio com o
item na interface do usurio.

ANDROID, uma viso geral Anderson Duarte de Amorim
170
Includo nas interfaces de ouvinte de evento so os mtodos de retorno seguintes:
onClick()
A partir do View.OnClickListener. chamado quando o usurio toca o item
(quando em modo de tocar), ou incide sobre o item com a navegao por teclas
ou trackball e pressiona a tecla "enter" ou pressiona o trackball.
onLongClick()
De View.OnLongClickListener. Isto chamado quando o usurio toca e prende
o item (quando no modo de tocar), ou incide sobre o item com a navegao por
teclas ou trackball e pressiona e mantm a tecla "enter" ou pressiona e mantm
pressionada a trackball (por um segundo).
onFocusChange()
De View.OnFocusChangeListener. Isto chamado quando o usurio navega
para ou longe do ponto, utilizando atalhos ou trackball.
onKey()
De View.OnKeyListener. Isto chamado quando o usurio est centrado sobre o
item e pressiona ou solta uma tecla no dispositivo.
onTouch()
De View.OnTouchListener. Isto chamado quando o usurio executa uma ao
qualificada como um evento de toque, incluindo pressionar, soltar, ou qualquer
movimento na tela (dentro dos limites do item).
onCreateContextMenu()
De View.OnCreateContextMenuListener. Isto chamado quando um menu de
contexto est sendo construdo (como o resultado de um "clique longo"
sustentado).
Esses mtodos so os nicos habitantes da suas respectivas interfaces. Para definir um
desses mtodos e lidar com seus eventos, implemente a interface aninhada em sua
ANDROID, uma viso geral Anderson Duarte de Amorim
171
atividade ou defina-a como uma classe annima. Em seguida, passe uma instncia da
sua aplicao com os respectivos mtodos View.set...Listener(). (Por exemplo, chamar
setOnClickListener() e pass-la a implementao do OnClickListener).
O exemplo abaixo mostra como registrar um receptor no clique de um boto.
// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
}
};

protected void onCreate(Bundle savedValues) {
...
// Capture our button from layout
Button button = (Button)findViewById(R.id.corky);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
...
}
Voc tambm pode achar mais conveniente para implementar OnClickListener como
parte de sua atividade. Isso ir evitar a carga horria extra e alocao de objetos. Por
exemplo:
public class ExampleActivity extends Activity implements OnClickListener {
protected void onCreate(Bundle savedValues) {
...
Button button = (Button)findViewById(R.id.corky);
button.setOnClickListener(this);
}

// Implement the OnClickListener callback
public void onClick(View v) {
// do something when the button is clicked
}
...
}
Observe que a chamada de onClick()no exemplo acima no tem valor de retorno, mas
alguns mtodos ouvintes devem retornar um boolean. A razo depende do evento. Para
os poucos que o fazem, aqui est o porqu:
onLongClick() - Retorna um booleano para indicar se voc tem consumido o
evento e que no deve ser levado adiante. Ou seja, retornar true para indicar que
voc tem tratado o evento e deve parar por aqui; retornar false se voc no tem
ANDROID, uma viso geral Anderson Duarte de Amorim
172
lidado com isso e/ou o evento deve continuar para qualquer outro receptor on-
click.
onKey() - Retorna um booleano para indicar se voc tem consumido o evento e
que no deve ser levada adiante. Ou seja, retornar true para indicar que voc tem
tratado o evento e deve parar por aqui; retornar false se voc no tem lidado com
isso e/ou o evento deve continuar a todo ouvinte on-key.
onTouch() - Retorna um booleano para indicar se o ouvinte consome este
evento. O importante que este evento pode ter vrias aes que se sucedem.
Ento, se voc retornar falso quando o evento de ao abaixo recebido, voc
indica que no consumiram o evento e tambm no esto interessados em aes
subseqentes deste evento. Assim, voc no ser chamado para outras aes
dentro do evento, como um gesto do dedo, ou um eventual evento de ao
acima.
Lembre-se que os principais eventos so sempre entregues para a corrente View em
foco. Eles so enviados a partir do topo da hierarquia de View e, em seguida, para
baixo, at chegar ao destino apropriado. Se a sua view (ou filho de sua view) atualmente
tem o foco, ento voc pode ver o curso de eventos atravs do mtodo
dispatchKeyEvent(). Como alternativa captura de eventos-chave atravs da sua view,
voc tambm pode receber todos os eventos dentro de sua atividade com onKeyDown()
e onKeyUp().
Nota: O Android vai chamar os manipuladores de eventos e depois os manipuladores
padro apropriados a partir da definio de segunda classe. Como tal, retornando true
destes ouvintes de evento ir parar a propagao do evento para ouvintes de eventos e
tambm ir bloquear o retorno de chamada para o manipulador de eventos padro no
View. Ento, tenha a certeza de que deseja encerrar o caso quando voc retornar true.
Manipuladores de eventos
Se voc est construindo um componente personalizado de view, ento voc vai ser
capaz de definir vrios mtodos de retorno usados como manipuladores de eventos
padro. No documento Construindo Componentes Personalizados, voc aprender a ver
alguns dos retornos comuns usados para tratamento de eventos, incluindo:
ANDROID, uma viso geral Anderson Duarte de Amorim
173
onKeyDown(int, KeyEvent) - Chamado quando um evento de nova tecla
ocorre.
onKeyUp(int, KeyEvent) - Chamado quando um evento de tecla para cima
ocorre.
onTrackballEvent(MotionEvent) - Chamado quando um evento de movimento
de trackball ocorre.
onTouchEvent(MotionEvent) - Chamado quando um evento do movimento da
tela de toque ocorre.
onFocusChanged(boolean, int, Rect) - Chamado quando a view ganha ou
perde o foco.
Existem alguns outros mtodos que voc deve estar ciente de que no so parte da
classe View, mas podem impactar diretamente a forma como voc capaz de manipular
eventos. Portanto, ao gerenciar eventos mais complexos dentro de um layout, considere
estes outros mtodos:
Activity.dispatchTouchEvent(MotionEvent) - Isso permite que sua atividade
possa interceptar todos os eventos de toque antes de serem enviados para a
janela.
ViewGroup.onInterceptTouchEvent(MotionEvent) - Isso permite que um
ViewGroup possa assistir a eventos como eles so distribudos aos views filhos.
ViewParent.requestDisallowInterceptTouchEvent(boolean) - Chamar esta
em cima de um pai view para indicar que ela no deve interceptar eventos de
contato com onInterceptTouchEvent(MotionEvent) .
Modo de toque
Quando um usurio est navegando uma interface de usurio com as teclas direcionais
ou um trackball, necessrio dar ateno aos itens de recurso (como botes) que o
usurio possa ver o que vai aceitar a entrada. Se o dispositivo tem capacidades de toque,
no entanto, o usurio comea a interagir com a interface ao toc-lo, ento ele no mais
ANDROID, uma viso geral Anderson Duarte de Amorim
174
necessrio para destacar itens, ou dar enfoque a uma viso particular. Assim, existe um
modo de interao com o nome "modo de toque."
Para um dispositivo sensvel ao toque, uma vez que o usurio toca a tela, o aparelho
entra em modo de tocar. Deste ponto em diante, somente as views em que o
isFocusableInTouchMode() est true podero ser focadas, como os widgets de edio
de texto. Outros views que so palpveis, como botes, no vo tirar o foco quando
tocado; eles vo simplesmente focar seus ouvintes com um clique, quando pressionados.
Toda vez que um usurio pressiona uma tecla direcional ou rola com uma trackball, o
aparelho sair do modo de tocar, e encontrar um visual de tirar o foco. Agora, o usurio
pode continuar interagindo com a interface do usurio sem tocar na tela.
O estado modo de tocar mantido ao longo de todo o sistema (todas as janelas e
atividades). Para consultar o estado atual, voc pode chamar isInTouchMode() para ver
se o dispositivo est no modo de tocar.
Manipulao do foco
O framework vai lidar com as rotinas de movimento do foco em resposta entrada do
usurio. Isso inclui a mudana do foco nas views que so removidas ou escondidas, ou
quando as views novos se tornam disponveis. Views indicam a sua disponibilidade para
tirar o foco atravs do mtodo isFocusable(). Para definir se uma View pode tirar o
foco, chame setFocusable(). Quando em modo de tocar, voc pode consultar se uma
View permite focar com isFocusableInTouchMode(). Voc pode mudar isso com
setFocusableInTouchMode().
Movimento do foco baseado em um algoritmo que encontra o vizinho mais prximo
em uma determinada direo. Em casos raros, o algoritmo padro pode no coincidir
com o comportamento desejado para o desenvolvedor. Nessas situaes, voc pode
fornecer substituies explcitas com os atributos XML a seguir no arquivo de layout:
nextFocusDown, nextFocusLeft, nextFocusRight, e nextFocusUp. Adicione um desses
atributos para o View a partir do qual o foco est saindo. Defina o valor do atributo a
ser o ID do view para quem o foco deve ser dado. Por exemplo:

ANDROID, uma viso geral Anderson Duarte de Amorim
175
<LinearLayout
android:orientation="vertical"
... >
<Button android:id="@+id/top"
android:nextFocusUp="@+id/bottom"
... />
<Button android:id="@+id/bottom"
android:nextFocusDown="@+id/top"
... />
</LinearLayout>
Normalmente, neste layout vertical, navegando a partir do primeiro boto no leva a
lugar nenhum, nem iria navegar abaixo do segundo boto. Agora que o boto superior
foi definido como um fundo com o nextFocusUp (e vice-versa), o foco de navegao ir
circular de cima para baixo e de baixo para cima.
Se voc gostaria de declarar o view como passvel de foco em sua interface do usurio
(quando no tradicional), adicione o atributo XML android:focusable para a view, na
sua declarao de layout. Defina o valor true. Voc pode tambm declarar uma view
como passvel de foco enquanto em modo de toque com
android:focusableInTouchMode.
Para solicitar uma exibio especial para ter foco, chame requestFocus().
Para ouvir os eventos de foco (ser notificado quando um view recebe ou perde foco),
use onFocusChange().

ANDROID, uma viso geral Anderson Duarte de Amorim
176
Notificar o usurio
Vrios tipos de situaes podem surgir que requerem a notificao do usurio sobre um
evento que ocorre em sua aplicao. Alguns eventos requerem que o usurio responda e
outros no. Por exemplo:
Quando um evento como salvar um arquivo for concluda, uma pequena
mensagem deve aparecer para confirmar que o salvamento foi bem sucedido.
Se o aplicativo executado em segundo plano e requer ateno do usurio, o
aplicativo deve criar uma notificao que permite ao usurio responder a
convenincia dele ou dela.
Se o aplicativo est executando o trabalho que o usurio deve aguardar (como
carregar um arquivo), o aplicativo deve mostrar uma roda de progresso pairando
ou uma barra.
Cada uma dessas tarefas de notificao podem ser conseguidas usando uma tcnica
diferente:
Uma notificao brinde, por breves mensagens que vm do fundo.
Uma notificao na barra de status, lembretes persistentes que vm do fundo e
solicitam resposta do usurio.
Uma notificao de dilogo, para as notificaes de atividades relacionadas.
Notificao brinde
Uma notificao brinde uma mensagem que aparece
na superfcie da janela. Ela s enche o espao
necessrio para a mensagem e a atividade atual do
usurio permanece visvel e interativa. A notificao
automaticamente desaparece, e no aceita eventos de
interao. Como um brinde pode ser criado a partir de um servio em background,
aparece mesmo que o aplicativo no esteja visvel.
ANDROID, uma viso geral Anderson Duarte de Amorim
177
Um brinde melhor para mensagens de texto curtas, como "Arquivo salvo", quando
voc est bastante certo de que o usurio est prestando a ateno na tela. Um brinde
no pode aceitar eventos de interao do usurio, se voc gostaria que o usurio
respondesse e agisse, considere usar uma notificao na barra de status.
Criando notificaes brinde
A imagem abaixo mostra uma notificao brinde de exemplo da aplicao do alarme.
Uma vez que um alarme ativado, um brinde exibido para garantir que o alarme foi
ajustado.
Um brinde pode ser criado e exibido a partir de uma
Activity ou Service. Se voc criar uma notificao de
brinde de um servio, ele aparece na frente da
atividade atualmente em foco.
Se a resposta do usurio com a notificao exigida,
considere usar uma notificao na barra de status.
O Bsico
Primeiro, instanciar um objeto Toast com um dos mtodos makeText(). Este mtodo usa
trs parmetros: a aplicao Context, a mensagem de texto e a durao para o brinde.
Ele retorna um objeto Toast inicializado corretamente. Voc pode exibir a notificao
brinde com show(), como mostrado no exemplo a seguir:
Context context = getApplicationContext();
CharSequence text = "Hello toast!";
int duration = Toast.LENGTH_SHORT;

Toast toast = Toast.makeText(context, text, duration);
toast.show();
Este exemplo demonstra tudo o que precisa para a maioria das notificaes brinde.
Raramente necessrio algo a mais. Voc pode, no entanto, querer a posio do brinde
diferente ou at mesmo usar o seu prprio layout, em vez de uma simples mensagem de
texto. As sees a seguir descrevem como voc pode fazer essas coisas.

ANDROID, uma viso geral Anderson Duarte de Amorim
178
Posicionar o seu brinde
Uma notificao brinde padro aparece perto da parte inferior da tela, centralizado
horizontalmente. Voc pode alterar esta posio com o mtodo setGravity(int, int, int).
Este aceita trs parmetros: a constante Gravity, um deslocamento da posio x e um
deslocamento da posio y.
Por exemplo, se voc decidir que o brinde deve aparecer no canto superior esquerdo,
voc pode definir a gravidade como este:
toast.setGravity(Gravity.TOP|Gravity.LEFT, 0, 0);
Se voc quiser deslocar a posio para a direita, aumente o valor do segundo parmetro.
Para empurr-lo para baixo, aumente o valor do ltimo parmetro.
Criando uma exibio personalizada brinde
Se uma mensagem de texto simples no suficiente,
voc pode criar um layout personalizado para a sua
notificao brinde. Para criar um layout personalizado,
definir um layout de view, em XML ou no cdigo do
aplicativo, e passar a View raiz para o mtodo
setView(View).
Por exemplo, voc pode criar o layout para o brinde
visvel na imagem esquerda, com o seguinte XML
(salvo como toast_layout.xml):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toast_layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:background="#DAAA"
>
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="@+id/text"
ANDROID, uma viso geral Anderson Duarte de Amorim
179
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
</LinearLayout>
Observe que a identificao do elemento LinearLayout "toast_layout". Voc deve usar
essa identificao para inflar o layout do XML, como mostrado aqui:
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.toast_layout,
(ViewGroup) findViewById(R.id.toast_layout_root));

ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setImageResource(R.drawable.android);
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText("Hello! This is a custom toast!");

Toast toast = new Toast(getApplicationContext());
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
Primeiro, recupere o LayoutInflater com getLayoutInflater() (ou getSystemService()), e
depois infle o layout de XML usando inflate(int, ViewGroup). O primeiro parmetro o
ID do recurso layout e o segundo a View raiz. Voc pode usar esse layout inflado para
encontrar mais objetos view no layout, agora capturar e definir o contedo dos
elementos ImageView e TextView. Finalmente, crie um novo brinde com
Toast(Context) e defina algumas propriedades do brinde, tais como a gravidade e
durao. Em seguida, chame setView(View) e passe seu layout inflado. Agora voc
pode exibir o brinde com o seu layout personalizado, chamando show().
Nota: No use o construtor pblico para um brinde, a menos que v definir o layout
com setView(View). Se voc no tem um layout personalizado para o uso, voc deve
usar makeText(Context, int, int) para criar o Toast.
Notificao na barra de status
Uma notificao na barra de status adiciona um cone para
barra de status do sistema (com opcionais relgio/mensagem
de texto) e uma mensagem expandida na janela
"Notificaes". Quando o usurio seleciona a mensagem
ANDROID, uma viso geral Anderson Duarte de Amorim
180
expandida, o Android aciona uma Intent que definida pela notificao (geralmente
para lanar uma Activity). Voc tambm pode configurar a notificao para alertar o
usurio com um som, uma vibrao e as luzes piscando no dispositivo.
Este tipo de notificao ideal quando o aplicativo est funcionando em um servio de
fundo e h necessidade de notificar o usurio sobre um evento. Se voc precisa alertar o
usurio sobre um evento que ocorre durante a sua atividade que ainda est em foco,
considere usar uma notificao de dilogo em vez disso.
Criao de notificaes da barra de status
Uma notificao na barra de status deve ser usada para qualquer caso em que um
servio de background precisa alertar o usurio sobre um evento que exige uma
resposta. Um servio de fundo nunca deve iniciar uma atividade por conta prpria a fim
de receber a interao do usurio. O servio deveria criar uma notificao na barra de
status que vai lanar a atividade quando selecionado pelo usurio.
A imagem abaixo mostra a barra de status com um cone de notificao no lado
esquerdo.

A imagem seguinte mostra mensagem expandida de notificao na janela
"Notificaes". O usurio pode visualizar a janela de notificaes, puxando para baixo a
barra de status (ou selecionando Notificaes no menu de opes da Home).

O Bsico
Uma Activity ou Service pode iniciar uma notificao na barra de status. Porque uma
atividade pode executar aes somente quando ela est ativa e em foco, voc deve criar
suas notificaes de um servio. Desta forma, a notificao pode ser criada a partir do
ANDROID, uma viso geral Anderson Duarte de Amorim
181
fundo, enquanto o usurio est usando outra aplicao ou quando o dispositivo estiver
dormindo. Para criar uma notificao, voc deve usar duas classes: Notification e
NotificationManager.
Use uma instncia da classe Notification para definir as propriedades de sua notificao
na barra de status, como o cone da barra de status, a mensagem expandida e
configuraes extras, como um som para tocar. O NotificationManager um servio do
sistema Android que executa e gerencia todas as notificaes. Voc no pode instanciar
o NotificationManager. A fim de dar-lhe a sua notificao, voc deve recuperar uma
referncia para o NotificationManager com getSystemService() e ento, quando voc
quer notificar o usurio, pass-lo com seu objeto de notificao notify().
Para criar uma notificao de barra de status:
1. Obtenha uma referncia para o NotificationManager:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)
getSystemService(ns);
2. Instanciar a notificao:
int icon = R.drawable.notification_icon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();

Notification notification = new Notification(icon, tickerText, when);
3. Definir mensagem expandida e inteno da notificao:
Context context = getApplicationContext();
CharSequence contentTitle = "My notification";
CharSequence contentText = "Hello World!";
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
4. Passe a notificao ao NotificationManager:
private static final int HELLO_ID = 1;

mNotificationManager.notify(HELLO_ID, notification);
isso a. Seu usurio j foi notificado.
ANDROID, uma viso geral Anderson Duarte de Amorim
182
Gerenciando suas notificaes
O NotificationManager um servio do sistema que gerencia todas as notificaes.
Voc deve obter uma referncia a ele com o mtodo getSystemService(). Por exemplo:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
Quando voc quiser enviar sua notificao na barra de status, passar o objeto de
notificao ao NotificationManager com notify(int, Notification). O primeiro parmetro
o ID nico para a notificao e o segundo o objeto de notificao. O ID identifica a
notificao a partir da sua aplicao. Isso necessrio se voc precisa atualizar a
notificao (se o aplicativo gerencia diferentes tipos de notificaes) ou selecionar a
ao apropriada quando o usurio retornar para a sua aplicao atravs da inteno
definida na notificao.
Para apagar a notificao de barra de status quando o usurio seleciona a partir da janela
de notificaes, adicione a flag "FLAG_AUTO_CANCEL" de seu objeto de
notificao. Voc tambm pode limpar manualmente com cancel(int), passando-lhe a
identificao ou notificao ou limpar todas as suas notificaes com cancelAll().
Criando uma notificao
Um objeto Notification define os detalhes da mensagem de notificao que exibida na
barra de status e janela de "Notificaes", e qualquer alerta de outras configuraes, tais
como sons e luzes piscando.
Uma notificao de barra de status exige o seguinte:
Um cone da barra de status
Uma mensagem expandida e ttulo para o modo expandido (a menos que voc
defina uma exibio personalizada ampliada)
Um PendingIntent, para ser acionado quando a notificao for selecionada
As configuraes opcionais para a notificao de barra de status incluem:
Uma mensagem de texto-relgio para a barra de status
Um som de alerta
ANDROID, uma viso geral Anderson Duarte de Amorim
183
Uma configurao vibrar
Uma definio LED piscando
O kit de arranque para uma nova notificao inclui o construtor Notification(int,
CharSequence, long) e o mtodo setLatestEventInfo(Context, CharSequence,
CharSequence, PendingIntent). Estes definem todas as definies necessrias para uma
notificao. O trecho a seguir demonstra a configurao de notificao de base:
int icon = R.drawable.notification_icon; // icon from resources
CharSequence tickerText = "Hello"; // ticker-text
long when = System.currentTimeMillis(); // notification time
Context context = getApplicationContext(); // application Context
CharSequence contentTitle = "My notification"; // expanded message title
CharSequence contentText = "Hello World!"; // expanded message text

Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

// the next two lines initialize the Notification, using the configurations above
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
Atualizando a notificao
Voc pode atualizar as informaes em sua notificao de barra de status como eventos
que continuam a ocorrer em seu aplicativo. Por exemplo, quando uma nova mensagem
de texto SMS chega antes que as mensagens anteriores foram lidas, o aplicativo de
mensagens atualiza as notificaes existentes para exibir o nmero total de novas
mensagens recebidas. Esta prtica, de uma atualizao de notificao existente muito
melhor do que a adio de novas notificaes NotificationManager porque evita a
desordem na janela de notificaes.
Porque cada notificao unicamente identificada pelo NotificationManager com um
nmero de identificao inteiro, voc pode revisar a notificao chamando
setLatestEventInfo() com novos valores, mudar alguns valores de campo da notificao,
e depois chamar notify() novamente.
Voc pode rever cada propriedade com os campos de membro de objeto (exceto para o
contexto e no ttulo da mensagem expandida e texto). Voc deve sempre revisar a
mensagem de texto quando voc atualizar a notificao chamando setLatestEventInfo()
com novos valores para contentTitle e contentText. Em seguida, chamar notify() para
ANDROID, uma viso geral Anderson Duarte de Amorim
184
atualizar a notificao. (Claro, se voc criou uma exibio personalizada expandida,
atualizar esses valores de texto e ttulo no ter efeito)
Adicionando um som
Voc pode alertar o usurio com o som de notificao padro (que definido pelo
usurio) ou com um som especificado pelo seu aplicativo.
Para utilizar o usurio padro do som, adicione "DEFAULT_SOUND" para o campo de
padres:
notification.defaults |= Notification.DEFAULT_SOUND;
Para usar um som diferente com as suas notificaes, passe uma referncia URI para o
campo de som. O exemplo a seguir usa um arquivo de udio conhecido gravado no
carto SD do dispositivo:
notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
No prximo exemplo, o arquivo de udio escolhido do MediaStore 's ContentProvider:
notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
Neste caso, a identificao exata do arquivo de mdia ("6") conhecido e anexado ao
contedo Uri. Se voc no souber a identificao exata, voc deve consultar todos os
meios disponveis no MediaStore com ContentResolver.
Se voc deseja que o som repeta continuamente at que o usurio responda notificao
ou a notificao seja cancelada, adicione "FLAG_INSISTENT" para o campo de
sinalizadores.
Nota: Se o campo padro inclui "DEFAULT_SOUND", ento o som padro substitui
qualquer som definido pelo campo de som.
Adicionando vibrao
Voc pode alertar o usurio com o modelo padro de vibrao ou com um modelo de
vibrao definido pelo seu aplicativo.
Para usar o modelo padro, adicione "DEFAULT_VIBRATE" para o campo de
padres:
ANDROID, uma viso geral Anderson Duarte de Amorim
185
notification.defaults |= Notification.DEFAULT_VIBRATE;
Para definir o seu padro de vibrao prpria, passe uma matriz de valores longos para o
campo vibrar:
long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate;
O longo array define o padro alternado para o comprimento de vibrao e desligando
(em milissegundos). O primeiro valor o tempo de espera (desligado) antes de comear,
o segundo valor o comprimento da primeira vibrao, o terceiro o comprimento da
prxima, e assim por diante. O padro pode ser to longo quanto queira, mas no pode
ser configurado para repetir.
Nota: Se o campo padro inclui "DEFAULT_VIBRATE", ento a vibrao padro
substitui qualquer vibrao definida pelo campo vibrate.
Adicionando luzes a piscar
Para alertar o usurio com luzes LED, voc pode implementar o modelo de luz padro
(se disponvel), ou definir sua prpria cor e padro para as luzes.
Para usar a configurao padro de luz, acrescentar "DEFAULT_LIGHTS" para o
campo de padres:
notification.defaults |= Notification.DEFAULT_LIGHTS;
Para definir sua prpria cor e padro, definir um valor para o campo ledARGB (para a
cor), o campo ledOffMS (perodo de tempo, em milsimos de segundo, para manter a
luz apagada), o ledOnMS (perodo de tempo, em milissegundos, para manter a luz
acesa), e tambm adicionar "FLAG_SHOW_LIGHTS" para o campo flags:
notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
Neste exemplo, a luz verde pisca vrias vezes a cada 300 milsimos de segundo e
desliga por um segundo. Nem todas as cores no espectro so suportadas pelo dispositivo
de LEDs, e no todo dispositivo que suporta as mesmas cores, ento o hardware
estima para o melhor de sua capacidade. Verde a cor mais comum de notificao.
ANDROID, uma viso geral Anderson Duarte de Amorim
186
Mais recursos
Voc pode adicionar vrias caractersticas a mais s suas notificaes usando campos de
notificao e flags. Algumas caractersticas teis incluem o seguinte:
"FLAG_AUTO_CANCEL"
Adicione isto ao campo de sinalizadores para cancelar automaticamente a
notificao depois que ela selecionada a partir da janela de notificaes.
"FLAG_INSISTENT"
Adicione isto ao campo de sinalizadores para repetir o udio at que o usurio
responda.
"FLAG_ONGOING_EVENT"
Adicione isto ao campo de sinalizadores para agrupar notificaes ao abrigo do
ttulo "em curso" da janela de notificaes. Isso indica que o aplicativo est em
curso - seus processos ainda esto em execuo em segundo plano, mesmo
quando o aplicativo no visvel (como a msica ou uma chamada de telefone).
"FLAG_NO_CLEAR"
Adicione isto ao campo de sinalizadores para indicar que a notificao no deve
ser limpa pelo boto "Limpar notificaes". Isso particularmente til se a sua
notificao est em curso.
nmero
Esse valor indica o nmero atual de eventos representados pela notificao. O
nmero apropriado sobreposto em cima do cone da barra de status. Se voc
pretende usar esse campo, ento voc deve comear com "1" quando a
notificao for criado pela primeira vez. (Se voc alterar o valor de zero para
qualquer coisa maior durante uma atualizao, o nmero no mostrado.)

ANDROID, uma viso geral Anderson Duarte de Amorim
187
iconLevel
Esse valor indica o nvel atual de um LevelListDrawable que usado para o
cone de notificao. Voc pode animar o cone na barra de status, alterando esse
valor para correlacionar com os drawable definido em um LevelListDrawable.
Criar uma exibio personalizada expandida
Por padro, o modo expandido utilizado na janela
"Notificaes" inclui um ttulo de base e mensagem de
texto. Estes so definidos por parmetros contentText e
contentTitle do mtodo setLatestEventInfo(). No
entanto, voc tambm pode definir um layout
personalizado para o modo de exibio expandido
usando RemoteViews. A imagem direita mostra um exemplo de uma exibio
personalizada alargada, que usa um ImageView e TextView em LinearLayout.
Para definir seu prprio layout para a mensagem expandida, instancie um objeto
RemoteViews e passe-o para o campo contentView da sua notificao. Passe o
PendingIntent ao campo contentIntent.
Criar uma exibio personalizada expandido mais bem entendido com um exemplo:
1. Criar o layout XML para a exibio expandida. Por exemplo, crie um arquivo
chamado layout custom_notification_layout.xml e construa-o assim:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3dp"
>
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#000"
/>
</LinearLayout>

ANDROID, uma viso geral Anderson Duarte de Amorim
188
Este esquema utilizado para a visualizao expandida, mas o contedo do
ImageView e TextView ainda precisam ser definidos pelo aplicativo.
RemoteViews oferece alguns mtodos adequados que lhe permitem definir o
contedo...
2. No cdigo do aplicativo, use os mtodos RemoveViews para definir a imagem e
texto. Em seguida, passe o objeto RemoteViews ao campo contentView da
notificao, conforme mostrado neste exemplo:
RemoteViews contentView = new RemoteViews(getPackageName(),
R.layout.custom_notification_layout);
contentView.setImageViewResource(R.id.image, R.drawable.notification_image);
contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded
view");
notification.contentView = contentView;
Como mostrado aqui, passe o nome do aplicativo do pacote e a identificao de
recursos de layout para o construtor RemoteViews. Em seguida, defina o
contedo para o ImageView e TextView, usando o setImageViewResource() e
setTextViewText(). Em cada caso, passe o ID de referncia do objeto View
conveniente que voc deseja definir, juntamente com o valor para essa viso.
Finalmente, o objeto RemoteViews passado para a notificao no mbito
contentView.
3. Porque voc no precisa do mtodo setLatestEventInfo() quando usando uma
exibio personalizada, voc deve definir as intenes para a notificao com o
campo contentIntent, como neste exemplo:
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
4. A notificao pode ser enviada, como de costume:
mNotificationManager.notify(CUSTOM_VIEW_ID, notification);
A classe RemoteViews tambm inclui mtodos que voc pode usar para facilmente
adicionar um Chronometer ou ProgressBar na view expandida da notificao. Para obter
mais informaes sobre como criar layouts personalizados com RemoteViews, consulte
o RemoteViews.
ANDROID, uma viso geral Anderson Duarte de Amorim
189
Nota: Ao criar uma view expandida customizada, voc deve tomar cuidado especial
para garantir que as funes personalizadas de seu layout haja corretamente no
dispositivo em orientaes e resolues diferentes. Enquanto este conselho se aplica a
todos os layouts view criados no Android, especialmente importante neste caso
porque o seu layout de propriedade real muito restrito. Portanto, no faa o seu
layout personalizado demasiado complexo e no se esquea de test-lo em vrias
configuraes.
Notificao de dilogo
Um dilogo geralmente uma pequena janela que
aparece na frente da atividade atual. A atividade perde
o foco e o dilogo aceita a interao do usurio. Os
dilogos so normalmente utilizados para notificaes
e atividades curtas que se relacionem diretamente com a aplicao em curso.
Voc deve usar uma caixa de dilogo quando voc precisa mostrar uma barra de
progresso ou uma mensagem curta que requer a confirmao do usurio (como um
alerta com "OK" e "Cancelar"). Voc pode usar tambm as janelas como parte
integrante na interface do aplicativo e para outros fins alm de notificaes. Para uma
discusso completa sobre todos os tipos disponveis de dilogos, incluindo seus usos
para as notificaes, consulte Criando caixas de dilogo.

ANDROID, uma viso geral Anderson Duarte de Amorim
190
Aplicando estilos e temas
Um estilo um conjunto de propriedades que especificam o aspecto e formato de um
View ou janela. Um estilo pode especificar propriedades como altura, padding, cor de
fonte, tamanho de fonte, cor de fundo e muito mais. Um estilo definido em um recurso
de XML que separado do XML que especifica o layout.
Estilos em Android compartilham uma filosofia semelhante de estilo em cascata em
web-design que permitem a voc separar o design do contedo.
Por exemplo, usando um estilo, voc pode ter este layout XML:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="@string/hello" />
E transformar nisso:
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
Todos os atributos relacionados com o estilo foram removidos do layout XML e
colocado em uma definio de estilo chamado CodeFont, e depois aplicado com o
atributo style. Voc ver a definio para esse estilo na seo seguinte.
Um tema um estilo aplicado a toda uma Activity ou aplicao, ao invs de um
indivduo View (como no exemplo acima). Quando um estilo aplicado como um tema,
a cada view da atividade ou da aplicao sero aplicados cada propriedade de estilo que
ele suporta. Por exemplo, voc pode aplicar o mesmo estilo CodeFont como um tema
para uma atividade e, em seguida, todo o texto dentro dessa atividade dever ter fonte
monoespaada verde.
Definio de estilos
Para criar um conjunto de estilos, salve um arquivo XML no diretrio res/values/ do seu
projeto. O nome do arquivo XML arbitrrio, mas deve usar a extenso .xml e ser salvo
na pasta res/values/.
O n raiz do arquivo XML deve ser <resources>.
Para cada estilo que voc quer criar, adicione um elemento <style> para o arquivo com
um nome que identifica o estilo (este atributo obrigatrio). Em seguida, adicione um
elemento <item> para cada propriedade desse estilo, com um nome que declara a
ANDROID, uma viso geral Anderson Duarte de Amorim
191
propriedade de estilo e um valor para ir com ele (este atributo obrigatrio). O valor
para o <item> pode ser uma seqncia de palavras-chave, uma cor hexadecimal, uma
referncia a outro tipo de recurso, ou outro valor, dependendo da propriedade de estilo.
Aqui est um exemplo de arquivo com um estilo nico:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
Cada filho do elemento <resources> convertido em um objeto de recurso do aplicativo
em tempo de compilao, que pode ser referenciado pelo valor do atributo name do
elemento <style>. Este estilo de exemplo pode ser referenciado a partir de um layout
XML como @style/CodeFont (como demonstrado na introduo acima).
O atributo parent no elemento <style> opcional e especifica o ID do recurso de um
outro estilo a partir do qual este estilo deve herdar propriedades. Voc pode, ento,
substituir as propriedades de estilo herdado se voc quiser.
Lembre-se, um estilo que voc deseja usar como uma atividade ou tema de aplicao
definido em XML exatamente do mesmo jeito que um estilo para uma view. Um estilo,
como o definido acima pode ser aplicado como um estilo para uma nica view ou como
um tema para uma atividade ou aplicao inteira. Como aplicar um estilo para uma
viso nica ou como um tema de aplicao discutido mais tarde.
Herana
O atributo parent no elemento <style> permite que voc especifique um estilo a partir
do qual o seu estilo deve herdar propriedades. Voc pode usar isso para herdar
propriedades de um estilo existente e, em seguida, definir apenas as propriedades que
deseja alterar ou acrescentar. Voc pode herdar de estilos que voc criou para si mesmo
ou de diferentes estilos que esto construdos na plataforma (Veja Usando estilos e
temas da plataforma abaixo, para obter informaes sobre herana de estilos definidos
pela plataforma Android). Por exemplo, voc pode herdar a aparncia do texto padro
da plataforma Android e, em seguida, modific-lo:
ANDROID, uma viso geral Anderson Duarte de Amorim
192
<style name="GreenText" parent="@android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
Se voc quer herdar os estilos que voc definiu para si mesmo, voc no tem que usar o
atributo parent. Em vez disso, apenas preceda o nome do estilo que voc quer herdar ao
nome do seu novo estilo, separados por um perodo. Por exemplo, para criar um novo
estilo que herda o estilo CodeFont definido anteriormente, mas fazer a cor vermelha,
voc pode criar o novo estilo como este:
<style name="CodeFont.Red">
<item name="android:textColor">#FF0000</item>
</style>
Observe que no h atributo parent na tag <style>, mas porque o atributo name comea
com a CodeFont nome do estilo (que um estilo que voc criou), este estilo herda todas
as propriedades de estilo a partir desse estilo. Este estilo, em seguida, substitui a
propriedade android:textColor para tornar o texto vermelho. Voc pode fazer referncia
a este novo estilo como @style/CodeFont.Red.
Voc pode continuar herdando assim tantas vezes quanto quiser, encadeando os nomes
com os perodos. Por exemplo, voc pode estender CodeFont.Red ser maior, com:
<style name="CodeFont.Red.Big">
<item name="android:textSize">30sp</item>
</style>
Este herda de ambos os estilos CodeFont e CodeFont.Red, em seguida, adiciona a
propriedade android:textSize.
Nota: Essa tcnica de herana por encadeando de nomes s funciona para estilos
definidos por seus prprios recursos. Voc no pode herdar estilos internos do Android
desta forma. Para fazer referncia a um estilo incorporado, como TextAppearance,
voc deve usar o atributo parent.
Propriedades do estilo
Agora que voc entende como um estilo definido, preciso saber que tipo de
propriedades de estilo definidas pelo <item> esto disponveis. Voc provavelmente
est familiarizado com alguns j, como layout_width e textColor. Claro, h muito mais
propriedades de estilo que voc pode usar.
ANDROID, uma viso geral Anderson Duarte de Amorim
193
O melhor lugar para encontrar propriedades que se aplicam a um determinado View a
referncia de classe correspondente, que lista todos os atributos XML que so
suportados. Por exemplo, todos os atributos listados na tabela de atributos XML
TextView podem ser usados em uma definio de estilo para um elemento TextView
(ou uma de suas subclasses). Um dos atributos listados na referncia
android:inputType, ento onde voc normalmente poderia colocar o atributo
android:inputType em um elemento <EditText>, assim:
<EditText
android:inputType="number"
... />
Voc pode em vez disso criar um estilo para o elemento EditText que inclua esta
propriedade:
<style name="Numbers">
<item name="android:inputType">number</item>
...
</style>
Portanto, o seu XML para o esquema pode agora aplicar este estilo:
<EditText
style="@style/Numbers"
... />
Este exemplo simples pode parecer dar mais trabalho, mas quando voc adiciona mais
propriedades de estilo e fatores na possibilidade de voltar a usar o estilo em vrios
lugares, o custo-beneficio pode ser enorme.
Para uma referncia de todas as propriedades de estilo disponveis, consulte a referncia
R.attr. Tenha em mente que todos os objetos view no aceitam todos os atributos de
mesmo estilo, ento voc deve, normalmente, referenciar ao especfico View para as
propriedades de estilo suportadas. Entretanto, se voc aplicar um estilo a uma exibio
que no suporta todas as propriedades de estilo, o view ir aplicar apenas as
propriedades que so suportadas e simplesmente ignorar os outros.
Algumas propriedades de estilo, no entanto, no so suportadas por qualquer elemento
View e s pode ser aplicado como um tema. Estas propriedades de estilo se aplicam a
toda a janela e no a qualquer tipo de view. Por exemplo, propriedades de estilo para um
tema podem ocultar o ttulo do aplicativo, ocultar a barra de status, ou mudar o fundo da
ANDROID, uma viso geral Anderson Duarte de Amorim
194
janela. Estes tipos de propriedades de estilo no pertencem a nenhum objeto View. Para
descobrir essas propriedades de estilo theme-only, veja o R.attr de referncia para os
atributos que comeam com window. Por exemplo, windowNoTitle e
windowBackground so propriedades de estilo que s so eficazes quando o estilo
aplicado como um tema para uma atividade ou aplicao. Consulte a prxima seo
para informaes sobre como aplicar um estilo como um tema.
Nota: No se esquea de prefixo dos nomes das propriedades em cada elemento
<item> com o android: namespace. Por exemplo: <item name="android:inputType">.
Aplicando estilos e temas para a interface do usurio
H duas maneiras de definir um estilo:
Para uma view individual, adicione o atributo style a um elemento view no
XML para seu layout.
Ou, para uma atividade inteira ou uma aplicao, adicione o atributo
android:theme ao elemento <activity> ou <application> no manifesto do
Android.
Quando voc aplica um estilo a uma nica View no layout, as propriedades definidas
pelo estilo so aplicadas somente ao View. Se um estilo aplicado a um ViewGroup, a
criana do elemento View no herdar as propriedades de estilo - apenas o elemento ao
qual se aplicam diretamente o estilo vai aplicar suas propriedades. No entanto, voc
pode aplicar um estilo para que se aplique a todos os elementos View, aplicando o estilo
como um tema.
Para aplicar uma definio de estilo como um tema, voc deve aplicar o estilo para uma
Activity ou aplicao no manifesto do Android. Quando voc fizer isso, todos os View
dentro da atividade ou da aplicao sero aplicveis a cada propriedade que ele suporta.
Por exemplo, se voc aplicar o estilo CodeFont dos exemplos anteriores a uma
atividade, ento todos os elementos View que suportam as propriedades de estilo de
texto ir aplic-los. Qualquer viso que no suporta as propriedades vai ignor-los. Se o
view suporta apenas algumas das propriedades, ento s aplicar essas propriedades.
Aplicar um estilo a uma view
Veja como definir um estilo para uma exibio no esquema XML:
ANDROID, uma viso geral Anderson Duarte de Amorim
195
<TextView
style="@style/CodeFont"
android:text="@string/hello" />
Agora este TextView ser denominado como definido pelo estilo chamado CodeFont.
(Veja o exemplo acima, em Definio de estilos).
Nota: O atributo style no usa o android: namespace prefix.
Aplicar um tema a uma atividade ou aplicao
Para definir um tema para todas as atividades de sua aplicao, abra o arquivo
AndroidManifest.xml e edite o tag <application> para incluir o atributo android:theme
com o nome do estilo. Por exemplo:
<application android:theme="@style/CustomTheme">
Se voc quer um tema aplicado a apenas uma atividade em seu aplicativo, ento,
adicione o atributo android:theme ao tag <activity> um de cada vez.
Assim como o Android oferece outros recursos internos, h muitos temas pr-definidos
que podem ser usados, para evitar escrev-los sozinho. Por exemplo, voc pode usar o
tema Dialog e fazer a sua actividade parecer como uma caixa de dilogo:
<activity android:theme="@android:style/Theme.Dialog">
Ou se voc quiser que o fundo seja transparente, usar o tema translcido:
<activity android:theme="@android:style/Theme.Translucent">
Se voc gosta de um tema, mas quer ajust-lo, basta adicionar o tema como o parent do
seu tema personalizado. Por exemplo, voc pode modificar o tradicional light theme
para usar a sua prpria cor, como esta:
<color name="custom_theme_color">#b0b0ff</color>
<style name="CustomTheme" parent="android:Theme.Light">
<item name="android:windowBackground">@color/custom_theme_color</item>
<item name="android:colorBackground">@color/custom_theme_color</item>
</style>
(Note que a cor precisa ser fornecida como um recurso separado aqui, porque o atributo
android:windowBackground suporta apenas uma referncia a outro recurso, ao contrrio
do android:colorBackground, a ele pode no ser dada uma cor literal.)
Agora use CustomTheme em vez de Theme.Light dentro do Manifesto Android:
ANDROID, uma viso geral Anderson Duarte de Amorim
196
<activity android:theme="@style/CustomTheme">
Selecione um tema baseado na verso de plataforma
Novas verses do Android tm temas adicionais disponveis para os aplicativos, e voc
pode querer usar estes durante a execuo nessas plataformas, enquanto continuam
sendo compatveis com verses anteriores. Voc pode fazer isso atravs de um tema
personalizado que usa a seleo de recursos para alternar entre os temas pai diferentes,
baseado na verso da plataforma.
Por exemplo, aqui est a declarao de um tema personalizado que simplesmente o
modelo padro das plataformas do tema light. Ele vai em um arquivo XML por
res/values (tipicamente res/values/styles.xml ):
<style name="LightThemeSelector" parent="android:Theme.Light">
...
</style>
Para este tema usar o novo tema hologrfico quando o aplicativo est rodando o
Android 3.0 (API Nvel 11) ou superior, voc pode colocar uma declarao alternativa
para o tema em um arquivo XML em res/values-v11, mas fazer do tema me o tema
hologrfico:
<style name="LightThemeSelector" parent="android:Theme.Holo.Light">
...
</style>
Agora, usar este tema como se fosse qualquer outro, e seu aplicativo passar
automaticamente para o tema hologrfico se em execuo no Android 3.0 ou superior.
Uma lista de atributos padro que voc pode usar em temas podem ser encontrados em
R.styleable.Theme.
Para obter mais informaes sobre o fornecimento de recursos alternativos, como os
temas e layouts, com base na verso de plataforma ou configuraes de outro
dispositivo, consulte o documento Fornecimento de Recursos.
Usando estilos e temas da plataforma
A plataforma Android oferece uma grande coleo de estilos e temas que voc pode
usar em seus aplicativos. Voc pode encontrar uma referncia de todos os estilos
disponveis na classe R.style. Para usar os estilos listados aqui, substituir todos os
ANDROID, uma viso geral Anderson Duarte de Amorim
197
sublinhados no nome do estilo, com um perodo. Por exemplo, voc pode aplicar o
Theme_NoTitleBar tema com "@android:style/Theme.NoTitleBar".
O R.style, entretanto, no bem documentado e no descreve minuciosamente os
estilos, assim, ver o cdigo fonte para estes estilos e temas lhe dar uma compreenso
melhor do que as propriedades de estilo de cada um oferece. Para uma melhor
referncia para estilos e temas do Android, consulte os seguintes cdigos fonte:
Android Styles (styles.xml)
Android Temas (themes.xml)
Esses arquivos vo te ajudar a aprender atravs do exemplo. Por exemplo, no cdigo
fonte de temas Android, voc encontrar uma declarao de <style
name="Theme.Dialog">. Nesta definio, voc ver todas as propriedades que so
usadas para estilo de dilogos que so usadas pelo framework Android.
Para uma referncia de atributos de estilo disponveis que voc pode usar para definir
um estilo ou tema (por exemplo, "windowBackground" ou "textAppearance"), ver R.attr
ou a classe View para o qual voc est criando um estilo.

ANDROID, uma viso geral Anderson Duarte de Amorim
198
Recursos de aplicao
Voc deve sempre externar recursos como imagens e seqncias de seu cdigo de
aplicao, para que voc possa mant-las de forma independente. Externalizar seus
recursos tambm permite que voc fornea recursos alternativos que oferecem suporte a
configuraes de dispositivos especficos, como lnguas ou tamanhos de tela diferentes,
o que se torna cada vez mais importante quanto mais dispositivos com Android tornam-
se disponveis com configuraes diferentes. A fim de proporcionar compatibilidade
com diferentes configuraes, voc deve organizar os recursos em seu diretrio do
projeto res/, usando vrios sub-diretrios que agrupam os recursos por tipo e
configurao.

Figura 1. Dois dispositivos diferentes, ambos os usando recursos padro.

Figura 2. Dois dispositivos diferentes, uma usando recursos alternativos.
Para qualquer tipo de recurso, voc pode especificar padro e vrios recursos
alternativos para a sua aplicao:
Os recursos padro so aqueles que devem ser utilizados independentemente da
configurao do aparelho ou quando no existem recursos alternativos que
correspondam configurao atual.
Recursos alternativos so aqueles que voc j projetou para uso com uma
configurao especfica. Para especificar que um grupo de recursos so de uma
configurao especfica, acrescente um qualificador de configurao adequada
ao nome do diretrio.
ANDROID, uma viso geral Anderson Duarte de Amorim
199
Por exemplo, enquanto o seu layout padro de interface do usurio salvo no diretrio
res/layout/, voc pode especificar um layout de interface diferente para ser usado
quando a tela est na orientao paisagem, salvando-o no diretrio res/layout-land/.
Android aplica automaticamente os recursos apropriados por correspondncia
configurao atual do dispositivo para os nomes do diretrio de recursos.
A figura 1 demonstra como um conjunto de recursos padro de um aplicativo so
aplicados a dois dispositivos diferentes, quando no h recursos alternativos
disponveis. A Figura 2 mostra o mesmo aplicativo com um conjunto de recursos
alternativos que se qualificam para uma das configuraes do dispositivo, assim, os dois
dispositivos usam recursos diferentes.
A informao acima apenas uma introduo sobre como trabalhar os recursos do
aplicativo no Android. Os documentos a seguir fornecem um guia completo de como
voc pode organizar seus recursos de aplicao, especificar os recursos alternativos,
acess-los em seu aplicativo, e mais:
Fornecendo recursos
Que tipos de recursos voc pode oferecer em seu aplicativo, onde guard-los, e
como criar recursos alternativos para configuraes de dispositivo especfico.
Acessando recursos
Como utilizar os recursos que voc forneceu, seja por referenci-los a partir do
seu cdigo de aplicativo ou de outros recursos XML.
Tratando alteraes em runtime
Como gerenciar as alteraes de configurao que ocorrem quando sua atividade
est em execuo.
Localizao
Um guia de baixo para cima para localizar seu aplicativo usando recursos
alternativos. Enquanto este apenas um uso especfico de recursos alternativos,
muito importante para alcanar mais usurios.

ANDROID, uma viso geral Anderson Duarte de Amorim
200
Tipos de recursos
Uma referncia de vrios tipos de recursos que voc pode fornecer, descrevendo
seus elementos XML, atributos e sintaxe. Por exemplo, esta referncia mostra
como criar um recurso para os menus do aplicativo, os desenhos, animaes e
muito mais.

ANDROID, uma viso geral Anderson Duarte de Amorim
201
Armazenamento de dados
Android oferece vrias opes para voc guardar dados da aplicao persistente. A
soluo que voc escolher depende de suas necessidades especficas, tais como se os
dados devem ser privados da sua aplicao ou acessveis para outras aplicaes (e do
usurio) e quanto espao seus dados requerem.
Suas opes de armazenamento de dados so os seguintes:
Preferncias compartilhadas
Armazenar dados privados primitivos em pares chave-valor.
Armazenamento interno
Armazenar dados privados sobre a memria do dispositivo.
Armazenamento externo
Armazenar dados pblicos sobre o armazenamento compartilhado externo.
Bancos de dados SQLite
Armazenar dados estruturados em um banco privado.
Conexo de rede
Armazenar dados na web com seu servidor de rede prpria.
Android fornece uma maneira para que voc exponha seus dados pessoais, mesmo para
outras aplicaes - com um provedor de contedo. Um provedor de contedo um
componente opcional que expe acesso de leitura/gravao sua aplicao de dados,
sujeito a qualquer restrio que voc pretende impor. Para obter mais informaes sobre
como usar provedores de contedo, consulte a documentao de provedores de
contedo.
Utilizando preferncias compartilhadas
A classe SharedPreferences fornece um framework geral que permite salvar e recuperar
pares chave-valor persistente de tipos de dados primitivos. Voc pode usar
SharedPreferences para salvar os dados primitivos: booleans, floats, inteiros, longos, e
ANDROID, uma viso geral Anderson Duarte de Amorim
202
strings. Estes dados vo persistir nas sesses de usurio (mesmo se sua aplicao
morta).
Para obter um objeto SharedPreferences
para sua aplicao, use um dos dois
mtodos:
getSharedPreferences() - Use esta
opo se voc precisa de arquivos
de mltiplas preferncias
identificados pelo nome, que voc
especifica com o parmetro
primeiro.
getPreferences() - Use esta opo
se voc s precisa de um arquivo de
preferncias para a sua actividade. Porque este ser o nico arquivo de
preferncias para sua atividade, voc no fornece um nome.
Para escrever os valores:
1. Chame edit() para obter uma SharedPreferences.Editor.
2. Adicione valores com mtodos como putBoolean() e putString().
3. Empregue os novos valores com commit().
Para ler os valores, use mtodos SharedPreferences como getBoolean() e getString().
Aqui est um exemplo que salva uma preferncia para o modo silencioso keypress em
uma calculadora:
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";

@Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .

// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
Preferncias do usurio
Preferncias compartilhadas no so
estritamente para o salvar "as preferncias do
usurio", como o toque de um usurio
escolheu. Se voc est interessado em criar
preferncias do usurio para seu aplicativo,
consulte PreferenceActivity , que estabelece
um quadro de atividades para voc criar as
preferncias do usurio, o qual ser
automaticamente persistido (usando as
preferncias compartilhadas).
ANDROID, uma viso geral Anderson Duarte de Amorim
203

@Override
protected void onStop(){
super.onStop();

// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);

// Commit the edits!
editor.commit();
}
}
Usando o armazenamento interno
Voc pode salvar arquivos diretamente na memria interna do dispositivo. Por padro,
os arquivos salvos no armazenamento interno so privados para sua aplicao e outras
aplicaes no podem acess-los (nem mesmo o usurio). Quando o usurio desinstala o
aplicativo, esses arquivos so removidos.
Para criar e gravar um arquivo privado para o armazenamento interno:
1. Chame openFileOutput() com o nome do arquivo e o modo de funcionamento.
Isso retorna um FileOutputStream.
2. Escreva no arquivo com o write().
3. Feche o fluxo com close().
Por exemplo:
String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
MODE_PRIVATE ir criar o arquivo (ou substituir um arquivo de mesmo nome) e
torn-lo privado para sua aplicao. Outras modalidades disponveis so:
MODE_APPEND, MODE_WORLD_READABLE e MODE_WORLD_WRITEABLE.


ANDROID, uma viso geral Anderson Duarte de Amorim
204
Para ler um arquivo de armazenamento interno:
1. Chame openFileInput() e passe o nome do arquivo a ser lido. Isso retorna um
FileInputStream.
2. Leia os bytes do arquivo com a read().
3. Em seguida, feche o fluxo com close().
Dica: Se voc quiser salvar um arquivo esttico em seu aplicativo em tempo de
compilao, salve o arquivo no diretrio de res/raw/ do seu projeto. Voc pode abri-lo
com openRawResource(), passando a identificao de recurso R.raw.<filename>. Esse
mtodo retorna um InputStream que voc pode usar para ler o arquivo (mas voc no
pode escrever no arquivo original).
Salvando os arquivos de cache
Se voc gostaria de gravar alguns dados em cache, ao invs de armazen-lo
persistentemente, voc deve usar getCacheDir() para abrir um arquivo que representa o
diretrio interno onde a sua aplicao deve salvar os arquivos de cache temporrio.
Quando o dispositivo est com pouco espao de armazenamento interno, o Android
pode excluir esses arquivos de cache para recuperar espao. No entanto, voc no deve
confiar no sistema para limpar esses arquivos para voc. Voc deve sempre manter os
arquivos de cache e manter dentro de um limite razovel de espao consumido, como
1MB. Quando o usurio desinstala o aplicativo, esses arquivos so removidos.
Outros mtodos teis:
getFilesDir()
Obtm o caminho absoluto para o diretrio de arquivos onde os arquivos
internos so salvos.
getDir()
Cria (ou abre um existente) diretrio dentro de seu espao de armazenamento
interno.
deleteFile()
Exclui um arquivo salvo na memria interna.
ANDROID, uma viso geral Anderson Duarte de Amorim
205
fileList()
Retorna uma matriz de arquivos atualmente salvos pela sua aplicao.
Usando o armazenamento externo
Cada dispositivo compatvel com o Android suporta um "armazenamento externo"
compartilhado que voc pode usar para salvar arquivos. Pode ser uma mdia de
armazenamento removvel (como um carto SD) ou uma memria interna (no
removvel). Os arquivos salvos no armazenamento externos so de leitura e podem ser
modificados pelo usurio quando permitem armazenamento em massa USB para
transferir arquivos de um computador.
Ateno: os arquivos externos podem desaparecer se o usurio monta o
armazenamento externo em um computador ou remove a mdia, e no h nenhuma
segurana aplicada sobre os arquivos que voc salva para o armazenamento externo.
Todas as aplicaes podem ler e gravar arquivos colocados no armazenamento externo
e o usurio pode remov-los.
Verificar a disponibilidade dos meios
Antes de fazer qualquer trabalho com o armazenamento externo, voc deve sempre
chamar getExternalStorageState() para verificar se os meios de comunicao esto
disponveis. A mdia pode ser montada a um computador, faltando, somente leitura, ou
em algum outro estado. Por exemplo, aqui est como voc pode verificar a
disponibilidade:
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();

if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
ANDROID, uma viso geral Anderson Duarte de Amorim
206
Este exemplo verifica se o armazenamento externo est disponvel para ler e escrever. O
mtodo getExternalStorageState() retorna outros estados que voc pode querer verificar,
como se a mdia est sendo compartilhada (conectada a um computador), est
totalmente ausente, foi mal removida, etc. Voc pode us-los para notificar o usurio
com mais informaes quando o aplicativo precisa de acesso mdia.
Acessando arquivos em armazenamento externo
Se voc estiver usando a API de nvel 8 ou superior, use getExternalFilesDir() para abrir
um arquivo que representa o diretrio de armazenamento externo onde voc deve salvar
seus arquivos. Este mtodo utiliza um parmetro type que especifica o tipo de
subdiretrio que voc deseja, como DIRECTORY_MUSIC e
DIRECTORY_RINGTONES (passe null para receber a raiz do diretrio do arquivo da
aplicativo). Este mtodo ir criar o diretrio apropriado, se necessrio. Ao especificar o
tipo de diretrio, voc garante que a mdia scanner do Android ir categorizar
corretamente seus arquivos no sistema (por exemplo, os ringtones so identificados
como toques, e no msica). Se o usurio desinstala o aplicativo, este diretrio e todo
seu contedo sero apagados.
Se voc estiver usando a API de nvel 7 ou inferior, use getExternalStorageDirectory()
para abrir um File que representa a raiz de armazenamento externo. Voc deve ento
escrever os seus dados no seguinte diretrio:
/Android/data/<package_name>/files/
O <package_name> o seu nome de estilo do pacote Java, tal como
"com.example.android.app". Se o dispositivo do usurio est executando API nvel 8 ou
superior e desinstalar o aplicativo, este diretrio e todo seu contedo sero apagados.
Como salvar arquivos que
devem ser compartilhados
Se voc deseja salvar os arquivos que
no so especficos para a sua
aplicao e que no devem ser
excludos quando o aplicativo
desinstalado, salva-os em um dos
Escondendo seus arquivos a partir da
Media Scanner
Inclua um arquivo vazio chamado .nomedia em seu
diretrio de arquivos externos (note o ponto prefixo
ao nome do arquivo). Isto ir prevenir o media
scanner do Android de ler arquivos de mdia e
inclu-los em aplicativos como Galley ou Music.
ANDROID, uma viso geral Anderson Duarte de Amorim
207
diretrios pblicos de armazenamento externo. Esses diretrios esto na origem do
armazenamento externo, como Music/, Pictures/, Ringtones/ e outros.
Na API nvel 8 ou superior, use getExternalStoragePublicDirectory(),passando para ele
o tipo de diretrio pblico que deseja, tais como DIRECTORY_MUSIC,
DIRECTORY_PICTURES, DIRECTORY_RINGTONES ou outros. Este mtodo ir
criar o diretrio apropriado, se necessrio.
Se voc estiver usando a API de nvel 7 ou inferior, use getExternalStorageDirectory()
para abrir um File que representa a raiz do armazenamento externo, em seguida, salve
seus arquivos compartilhados em um dos seguintes diretrios:
Music/ - o scanner media classifica todas as mdias encontradas aqui como a
msica do usurio.
Podcasts/ - scanner media classifica todas as mdias encontradas aqui como um
podcast.
Ringtones/ - scanner media classifica todas as mdias encontradas aqui como um
ringtone.
Alarms/ - scanner media classifica todas as mdias encontradas aqui como um
som de alarme.
Notifications/ - scanner media classifica todas as mdias encontradas aqui como
um som de notificao.
Pictures/ - todas as fotos (excluindo as tiradas com a cmera).
Movies/ - todos os filmes (excluindo aqueles filmados com a cmera de vdeo).
Download/ - downloads diversos.
Salvando os arquivos de cache
Se voc estiver usando a API de nvel ou superior, use 8 getExternalCacheDir() para
abrir um File que representa o diretrio de armazenamento externo, onde voc deve
salvar os arquivos de cache. Se o usurio desinstala o aplicativo, esses arquivos sero
automaticamente excludos. No entanto, durante a vida do seu aplicativo, voc deve
gerenciar esses arquivos de cache e eliminar os que no so necessrios, a fim de
preservar o espao do arquivo.
ANDROID, uma viso geral Anderson Duarte de Amorim
208
Se voc estiver usando a API de nvel 7 ou inferior, use getExternalStorageDirectory()
para abrir um File que representa a raiz do armazenamento externo, em seguida, escreva
o seu cache de dados no seguinte diretrio:
/Android/data/<package_name>/cache/
O <package_name> o seu estilo nome do pacote Java, tal qual
"com.example.android.app".
Utilizando bancos de dados
Android oferece suporte completo para bancos de dados SQLite. Qualquer banco de
dados que voc criar sero acessveis pelo nome de qualquer classe na aplicao, mas
no fora da aplicao.
O mtodo recomendado para criar um novo banco de dados SQLite criar uma
subclasse de SQLiteOpenHelper e substituir o mtodo onCreate(), no qual voc pode
executar um comando SQLite para criar tabelas no banco de dados. Por exemplo:
public class DictionaryOpenHelper extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 2;
private static final String DICTIONARY_TABLE_NAME = "dictionary";
private static final String DICTIONARY_TABLE_CREATE =
"CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +
KEY_WORD + " TEXT, " +
KEY_DEFINITION + " TEXT);";

DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DICTIONARY_TABLE_CREATE);
}
}
Voc pode obter uma instncia de sua implementao SQLiteOpenHelper usando o
construtor que voc definiu. Para escrever e ler a partir do banco de dados, chame
getWritableDatabase() e getReadableDatabase(), respectivamente. Estes devolvem um
objeto SQLiteDatabase que representa o banco de dados e fornece mtodos para
operaes de SQLite.
ANDROID, uma viso geral Anderson Duarte de Amorim
209
Voc pode executar consultas SQLite usando
mtodos query() SQLiteDatabase, que aceitam
parmetros de consulta diversos, tais como a tabela a
ser consultada, a projeo, seleo, colunas,
agrupamento e outros.
Cada consulta SQLite ir retornar um Cursor que
aponta para todos os registros encontrados pela
consulta. O Cursor sempre o mecanismo com o
qual voc pode navegar pelos resultados de uma
consulta de banco de dados e ler linhas e colunas.
Para aplicativos de exemplo que demonstram como
usar banco de dados SQLite no Android, consulte as
aplicaes Note Pad e Dicionrio pesquisvel.
Banco de dados de depurao
O Android SDK inclui uma ferramenta sqlite3 de banco de dados que permite que voc
navegue sobre o contedo da tabela, execute comandos SQL e execute outras funes
teis em bancos de dados SQLite.
Usando uma conexo de rede
Voc pode usar a rede (quando disponvel) para armazenar e recuperar dados sobre os
seus prprios servios baseados na web. Para fazer operaes de rede, use as classes dos
seguintes pacotes:
java.net.*
android.net.*
Android no impe qualquer
limitao para alm dos conceitos-
padro SQLite. Ns
recomendamos incluir um valor de
campo autoincrementado como
chave que pode ser usado como
uma identificao nica para
localizar rapidamente um registro.
Isso no necessria para dados
privados, mas se voc
implementar um provedor de
contedo, voc deve incluir uma
identificao exclusiva com a
constante BaseColumns._ID.
ANDROID, uma viso geral Anderson Duarte de Amorim
210
Artigos
Acessibilidade
Linguagens e recursos
Text-to-Speech TTS: tambm conhecido como speech synthesis (sntese de fala, em
portugus) um recurso disponibilizado a partir de Android 1.6 (API Level 4) que
possibilita ao dispositivo ler textos em diversas linguagens.
O mecanismo TTS embarcado no Android suporta ingls (britnico ou americano),
francs, alemo, italiano e espanhol e precisa saber qual idioma pronunciar para adequar
a voz, afinal, uma mesma palavra possui pronuncias diferentes dependendo da lngua.
Uma checagem da disponibilidade do recurso se faz necessrio tendo em vista que,
apesar de todos os dispositivos com Android terem a funcionalidade embarcada, alguns
possuem armazenamento limitado e pode ser que faltem arquivos de recursos
especficos do idioma, sendo assim, o seguinte cdigo verifica a presena dos recursos
TTS.
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, MY_DATA_CHECK_CODE);
Uma checagem que retorna sucesso marcada por CHECK_VOICE_DATA_PASS indicando
que o dispositivo est pronto para falar, depois da criao do objeto TextToSpeech.
Em caso negativo, o dispositivo ir utilizar o ACTION_INSTALL_TTS_DATA que
dispara uma ao levando o usurio a fazer a instalao manualmente acessando o
Android Market; A instalao feita automaticamente aps a concluso do download.
Uma implementao da verificao do resultado da checagem est abaixo:
private TextToSpeech mTts;
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
mTts = new TextToSpeech(this, this);
} else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(
TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
ANDROID, uma viso geral Anderson Duarte de Amorim
211
}
} }
No construtor da instncia TextToSpeech ns passamos uma referncia ao Contexto a
ser usado (neste caso a atividade atual), e um OnInitListener (aqui a nossa atividade
tambm). Dessa forma habilitado para que a aplicao seja notificada quando o Text-
To-Speech totalmente carregado, ento podemos comear a configurar-lo e us-lo.
Linguagens e localidade
No Google I/O 2009 foi mostrado uma utilizao do TTS para falar o resultado de uma
traduo de e para uma das lnguas disponveis. Um exemplo de chamada como o
abaixo:
mTts.setLanguage(Locale.US);
Ou para verificar se uma linguagem est disponvel, basta usar o trecho abaixo que
retornar TextToSpeech.LANG_COUNTRY_AVAILABLE para indicar que o idioma
e o pas, como descrito pelo parmetro de localidade, so suportados (e os dados esto
corretamente instalados), como tambm pode retornar
TextToSpeech.LANG_AVAILABLE indicando que a lngua est disponvel ou o
oposto TextToSpeech.LANG_MISSING_DATA.
mTts.isLanguageAvailable(Locale.UK))
mTts.isLanguageAvailable(Locale.FRANCE))
mTts.isLanguageAvailable(new Locale("spa", "ESP")))
Obs.: para usar o cdigo Locale.getDefault(), deve-se certificar primeiramente se o
idioma padro suportado.
Fazendo o dispositivo falar
A maneira mais simples de fazer isso usando o mtodo speak() como:
String myText1 = "Did you sleep well?";
String myText2 = "I hope so, because it's time to wake up.";
mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, null);
mTts.speak(myText2, TextToSpeech.QUEUE_ADD, null);
O mecanismo TTS gerencia uma fila global de todas as entradas para sintetizar, que
tambm so conhecidos como "expresses". Cada TextToSpeech pode gerir sua prpria
fila a fim de controlar o que vai interromper a emisso atual e que simplesmente uma
fila de espera.
ANDROID, uma viso geral Anderson Duarte de Amorim
212
No Android, cada stream de udio que reproduzido est associado a um tipo de fluxo,
tal como definido no android.media.AudioManager . Para um despertador falando, o
texto a ser reproduzido pertence ao tipo de fluxo AudioManager.STREAM_ALARM,
para que ele respeite as definies de alarme que o usurio escolheu no dispositivo. O
ltimo parmetro do mtodo speak() permite que voc passe para os parmetros do
TTS, especificado como pares chave / valor em um HashMap, tal qual:
HashMap<String, String> myHashAlarm = new HashMap();
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_ALARM));
mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm);
Como as chamadas so assncronas, pode ser necessrio identificar se uma sntese foi
concluda, isso pode ser feito da seguinte forma:
mTts.setOnUtteranceCompletedListener(this);
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_ALARM));
mTts.speak(myText1, TextToSpeech.QUEUE_FLUSH, myHashAlarm);
myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
"end of wakeup message ID");
// myHashAlarm now contains two optional parameters
mTts.speak(myText2, TextToSpeech.QUEUE_ADD, myHashAlarm);
E a atividade notificada pelo mtodo, repare que a mensagem foi usada para ser
identificada no mtodo:
public void onUtteranceCompleted(String uttId) {
if (uttId == "end of wakeup message ID") {
playAnnoyingMusic();
}
}
Como o recurso de fala exige bastante processamento, numa situao em que um
determinado texto ser lido diversas vezes mais interessante gravar o udio para ser
reproduzido posteriormente.
HashMap<String, String> myHashRender = new HashMap();
String wakeUpText = "Are you up yet?";
String destFileName = "/sdcard/myAppCache/wakeUp.wav";
myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, wakeUpText);
mTts.synthesizeToFile(wakuUpText, myHashRender, destFileName);
A funcionalidade de text-to-speech depende de um servio dedicado compartilhado
entre todos os aplicativos que usam esse recurso. Quando voc terminar de usar o TTS,
use a instruo mTts.shutdown() dentro do mtodo onDestroy(), por exemplo.
ANDROID, uma viso geral Anderson Duarte de Amorim
213
Interface
Toque
O modo de toque um estado da hierarquia de vista que depende unicamente da
interao do usurio com o telefone. Por si s, o modo de tocar algo muito fcil de
entender, pois ele simplesmente indica se a interao do usurio passado foi realizada
com a tela sensvel ao toque. Por exemplo, se voc estiver usando um dispositivo com
Android, a seleo de um widget com o trackball vai lev-lo sair do modo de tocar, no
entanto, se voc toca um boto na tela com seu dedo, voc entrar no modo de tocar.
Quando o usurio no estiver em modo de tocar, ns falamos sobre o modo de trackball,
o modo de navegao ou a navegao por teclado, por isso no se surpreenda se voc
encontrar esses termos.
Existe apenas uma API diretamente relacionada com o modo de toque,
View.isInTouchMode().
Curiosamente, o modo de tocar enganosamente simples e as conseqncias de entrar
no modo de tocar muito maior do que voc imagina. Vejamos algumas das razes.
Toque em modo de seleo e foco
Criar um conjunto de ferramentas UI para dispositivos mveis difcil porque so
vrios os mecanismos de interao. Alguns dispositivos oferecem apenas 12 teclas,
algumas tm uma tela sensvel ao toque, alguns exigem uma caneta, alguns tm ambos
um ecr tctil e um teclado. Com base nos recursos de hardware do usurio, ele pode
interagir com seu aplicativo usando mecanismos diferentes, ento tivemos que pensar
muito sobre todos os possveis problemas que possam surgir. Uma questo nos levou a
criar o modo de toque.
Imagine um aplicativo simples, ApiDemos por exemplo, que mostra uma lista de itens
de texto. O usurio pode navegar livremente pela lista usando a trackball, mas tambm,
em alternativa, deslocar e arremessar a lista usando a tela sensvel ao toque. O problema
neste cenrio como lidar com a seleo corretamente quando o usurio manipula a
lista atravs da tela sensvel ao toque.
Neste caso, se o usurio selecionar um item no topo da lista e ento arremessa a lista
para o fundo, o que deve acontecer com a seleo? E se ele permanecer no item e rolar
ANDROID, uma viso geral Anderson Duarte de Amorim
214
para fora da tela? O que deve acontecer se o usurio decidiu ento mover a seleo com
o trackball? Ou pior, o que deve acontecer se o usurio pressiona o trackball para agir
de acordo com o item selecionado, que no mostrado na tela mais?
Aps cuidadosa considerao, decidimos remover por completo a seleo, quando o
usurio manipula a interface do usurio atravs da tela sensvel ao toque.
No modo de toque, no h foco e no h seleo. Qualquer item selecionado em uma
lista de em uma grade fica desmarcada, logo que o usurio entra no modo de tocar. Da
mesma forma, quaisquer widgets ficaram desfocados quando o usurio entra no modo
de tocar. A imagem abaixo ilustra o que acontece quando o usurio toca uma lista
depois de selecionar um item com o trackball.

Para tornar as coisas mais naturais para o usurio, o quadro sabe como ressuscitar a
seleo / foco sempre que o usurio sai do modo de tocar. Por exemplo, se o usurio
fosse usar o trackball novamente, a seleo iria reaparecer no item previamente
selecionado. por isso que alguns desenvolvedores esto confusos quando se criar uma
exibio personalizada e comear a receber os principais eventos s depois de mover o
trackball uma vez: a sua aplicao est no modo de tocar, e eles precisam usar o
trackball para sair do modo de tocar e ressuscitar o foco.
ANDROID, uma viso geral Anderson Duarte de Amorim
215
A relao entre o modo de toque, seleo e foco significa que voc no deve confiar na
seleo e/ou foco existir em sua aplicao. Um problema muito comum com o Android
para novos desenvolvedores contar com ListView.getSelectedItemPosition(). No
modo de toque, este mtodo retornar INVALID_POSITION.
Focando no modo Touch
Em geral, o foco no existe no modo de tocar. No entanto, o foco pode existir no modo
de tocar em uma maneira muito especial chamado focusable. Este modo especial foi
criado para widgets que recebem a entrada de texto, como EditText ou ListView. O
modo focusable o que permite ao usurio inserir texto dentro de um campo de texto na
tela, sem primeiro selecion-la com a bola ou o dedo.
Quando um usurio toca a tela, o aplicativo ir entrar no modo de toque se ele no
estava no modo de tocar j. O que acontece durante a transio para o modo de tocar
depende do que o usurio tocou, e que atualmente tem foco. Se o usurio toca um
widget que focusable no modo de tocar, o widget ir receber o foco. Caso contrrio,
qualquer elemento ao qual se dedica atualmente no vai manter o foco a menos que seja
focusable no modo de tocar. Por exemplo, na figura abaixo, quando o usurio toca a
tela, o campo de texto recebe o foco.
Focusable no modo de uma propriedade que voc
pode definir a si mesmo, seja de cdigo ou de XML. No
entanto, voc deve us-lo com parcimnia e s em
situaes muito especficas, porque quebra a coerncia
com o comportamento normal da interface do Android.
Um jogo um bom exemplo de uma aplicao que pode
fazer bom uso do focusable na propriedade de modo
sensvel ao toque. MapView, se usada em tela cheia
como no Google Maps, outro bom exemplo de onde
voc pode usar focusable no modo de tocar
corretamente.
Abaixo est um exemplo de um widget focusable em modo de tocar. Quando o usurio
bate um AutoCompleteTextView com o dedo, o foco permanece no campo de texto de
entrada:
ANDROID, uma viso geral Anderson Duarte de Amorim
216

Novos desenvolvedores para o Android, muitas vezes pensam que focusable no modo
de tocar a soluo que eles precisam para "consertar" o problema do
"desaparecimento" da seleo/foco. Ns encorajamos voc a pensar muito antes de
utiliz-lo. Se usada incorretamente, pode fazer seu aplicativo se comportar de maneira
diferente do resto do sistema e simplesmente jogar fora os hbitos do usurio. O quadro
Android contm todas as ferramentas necessrias para lidar com as interaes do
usurio sem usar focusable no modo de tocar. Por exemplo, em vez de tentar fazer
ListView sempre manter a sua seleo, basta usar o modo de escolha apropriada, como
mostrado na setChoiceMode(int) .
Gestos
As telas de toque so uma tima maneira de interagir com aplicaes em dispositivos
mveis. Com uma tela de toque, os usurios podem facilmente tocar, arrastar,
arremessar ou deslizar rapidamente e realizar aes em seus aplicativos favoritos. Para
os desenvolvedores de aplicativos o Android faz com que seja fcil reconhecer aes
simples, mas tem sido mais difcil de lidar com gestos complicados, s vezes exigindo
que os desenvolvedores escrevam um monte de cdigo.
por isso que foi introduzida uma nova API de gestos no Android 1.6. Esta API,
localizada no novo pacote android.gesture , permite armazenar, carregar, desenhar e
reconhecer gestos. Clique para baixar o cdigo fonte dos exemplos
Mtodo de entrada de dados
A partir do Android 1.5, a plataforma Android oferece um Input Method Framework
(FMI) que permite a criao de mtodos de entrada na tela, como teclados virtuais. Este
artigo fornece uma viso geral de editores de mtodo de Android de entrada (IME) e o
que um aplicativo precisa fazer para trabalhar bem com eles. O FMI concebido para
ANDROID, uma viso geral Anderson Duarte de Amorim
217
apoiar novas classes de dispositivos Android, como os teclados sem hardware, por isso
importante que o aplicativo funcione bem com o FMI e oferece uma tima experincia
para os usurios.
O que um mtodo de entrada?
O FMI Android foi concebido para suportar uma variedade de IMEs, incluindo o
teclado virtual, reconhecedores de mo-escrita, e tradutores teclado duro. Nosso foco,
no entanto, ser em teclados virtuais, j que este o tipo de mtodo de entrada que
atualmente faz parte da plataforma.
Um usurio normalmente ir acessar o IME atual, tocando em uma exibio de texto
para editar, conforme mostrado na tela inicial:

O teclado virtual posicionado na parte inferior da tela sobre a janela do aplicativo.
Para organizar o espao disponvel entre a aplicao e o IME, usamos algumas
abordagens, a que mostrada aqui chamado de pan e digitalizar, e simplesmente
envolve a rolagem da janela do aplicativo em torno de modo que a viso focada
atualmente visvel. Este o modo padro, pois mais seguro para as aplicaes
existentes.
ANDROID, uma viso geral Anderson Duarte de Amorim
218
Na maioria das vezes o layout da tela um resize, onde a janela da aplicao
redimensionada para ser totalmente visvel. Um exemplo mostrado aqui, quando
escrevo uma mensagem de e-mail:

O tamanho da janela do aplicativo alterada para que nenhum deles seja escondido pelo
IME, permitindo acesso total ao aplicativo e IME. Isto, obviamente, s funciona para
aplicativos que tm uma rea redimensionvel que pode ser reduzida para dar espao
suficiente, mas o espao vertical neste modo realmente nada menos do que o que est
disponvel na orientao paisagem.
O principal modo final fullscreen ou modo de extrato. Isso usado quando o IME
muito grande para o espao compartilhar com a aplicao de base. Com o IME padro,
voc s vai encontrar essa situao quando a tela est em uma orientao horizontal,
embora IMEs sejam livres para us-lo sempre que desejarem. Neste caso, a janela da
aplicao deixada como est, e simplesmente o IME exibe a tela inteira em cima dela,
como mostrado aqui:
ANDROID, uma viso geral Anderson Duarte de Amorim
219

Porque o IME est cobrindo o aplicativo, ele tem a sua rea de edio prpria, o que
mostra o texto, na verdade contida na petio inicial. Existem tambm algumas
oportunidades limitadas aplicao que tem que personalizar as partes do IME para
melhorar a experincia do usurio.
Atributos bsicos XML para controlar IMEs
H uma srie de coisas que o sistema faz para tentar ajudar de trabalho existente com as
aplicaes IMEs to bem quanto possvel, tais como:
Use pan e scan por padro, a menos que possa razoavelmente supor que o modo
de redimensionar vai trabalhar pela existncia de listas, percorrer as exibies,
etc.
Analisar no TextView vrios atributos existentes para adivinhar o tipo de
contedo (nmeros, texto simples, senha, etc.) para ajudar o teclado a exibir um
esquema de chave apropriado.
Atribuir algumas aes padro para o IME fullscreen, como "campo prximo" e
"feito".
H tambm algumas coisas simples que voc pode fazer na sua aplicao que, muitas
vezes, melhoram significativamente sua experincia de usurio. Exceto quando
mencionado explicitamente, estes iro trabalhar em qualquer verso da plataforma
Android, mesmo os anteriores para o Android 1.5 (uma vez que ir simplesmente
ignorar essas novas opes).
Especificando cada tipo de controle de entrada EditText
A coisa mais importante para um pedido a fazer usar o novo atributo
android:inputType em cada EditText. O atributo fornece informao muito mais rica
ANDROID, uma viso geral Anderson Duarte de Amorim
220
sobre o contedo do texto. Este atributo realmente substitui muitos atributos existentes (
android: password , android: singleLine , android: numeric , android: phoneNumber ,
android: capitalize , android: autoText e android: editable). Se voc especificar os
atributos mais velhos e os novos android:inputType, o sistema usa android:inputType e
ignora as outras.
O android:inputType atributo tem trs partes:
A classe a interpretao geral de caracteres. As classes atualmente suportadas
so text (plain text), number (nmero decimal), phone (nmero de telefone), e
datetime (uma data ou hora).
A variao um refinamento da classe. No atributo, normalmente voc vai
especificar a classe e variante juntamente com a classe como um prefixo. Por
exemplo, textEmailAddress um campo de texto onde o usurio ir inserir algo
que um endereo de correio (foo@bar.com) para a disposio das teclas ter
um @ "carter" de acesso fcil, e numberSigned um campo numrico com um
sinal. Se somente a classe especificado, ento voc obtm o padro / variante
genrica.
Sinalizadores adicionais podem ser especificados de abastecimento de
refinamento. Esses sinalizadores so especficos para uma classe. Por exemplo,
alguns sinalizadores para o text de classe so textCapSentences, textAutoCorrect
e textMultiline.
Como exemplo, aqui o EditText novo para a aplicao do IM ver texto da mensagem:
<EditText android:id="@+id/edtInput"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textShortMessage|textAutoCorrect|textCapSentences|textMultiLine"
android:imeOptions="actionSend|flagNoEnterAction"
android:maxLines="4"
android:maxLength="2000"
android:hint="@string/compose_hint"/>
Ativar o modo de redimensionamento e funcionalidades outra janela
A segunda coisa mais importante para sua aplicao a fazer especificar o
comportamento global da sua janela em relao ao mtodo de entrada. O aspecto mais
ANDROID, uma viso geral Anderson Duarte de Amorim
221
visvel disto o controle redimensionar VS. pan e scan mode, mas existem outras coisas
que voc pode fazer bem para melhorar sua experincia de usurio.
Voc normalmente ir controlar esse comportamento atravs do
android:windowSoftInputMode em cada <activity> em sua AndroidManifest.xml.
Como o tipo de entrada, h um par de peas diferentes de dados que pode ser
especificado aqui, combinando-as entre si:
O modo de ajuste da janela especificado com adjustResize ou adjustPan .
altamente recomendado que voc especifique sempre um ou outro.
Voc ainda pode controlar se o IME ser exibido automaticamente quando sua
atividade exibida e outras situaes onde o usurio move a ele. O sistema no
mostrar automaticamente um IME, por padro, mas em alguns casos pode ser
conveniente para o usurio se uma aplicao permite esse comportamento. Voc
pode solicitar este com stateVisible . H tambm um nmero de opes de outro
estado para o controle mais detalhado que voc pode encontrar na
documentao.
Um exemplo tpico desse campo pode ser visto na atividade de edio do contato, o que
garante que ele redimensionado e exibe automaticamente o IME para o usurio:
<activity name="EditContactActivity"
android:windowSoftInputMode="stateVisible|adjustResize">
...
</activity>
Controlando os botes de ao
Para a personalizao final, vamos olhar para a "ao" de botes no IME. Existem
atualmente dois tipos de aes:
A tecla enter em um teclado virtual normalmente ligada a uma ao quando
no estiverem operando em um multi-line de edio de texto.
Quando em modo de tela cheia, um IME pode tambm colocar um boto de ao
adicional direita do texto que est sendo editado, dando ao usurio o acesso
rpido a uma operao de aplicativos comuns.
ANDROID, uma viso geral Anderson Duarte de Amorim
222
Estas opes so controladas com o atributo android:imeOptions em TextView . O valor
que voc fornecer aqui pode ser qualquer combinao de:
Uma das aes pr-definidas constantes ( actionGo , actionSearch , actionSend ,
actionNext , actionDone ). Se nenhum desses for especificado, o sistema ir
inferir qualquer actionNext ou actionDone dependendo se h um campo
focusable aps este, voc pode explicitamente forar a nenhuma ao com
actionNone.
O flagNoEnterAction informa o IME que a ao no deve estar disponvel na
tecla enter, mesmo que o texto em si no multi-linha. Isso evita ter aes
irrecuperveis (enviar) que pode ser tocado acidentalmente pelo usurio durante
a digitao.
O flagNoAccessoryAction remove o boto de ao da rea de texto, deixando
mais espao para o texto.
O flagNoExtractUi remove completamente a rea de texto, permitindo que o
aplicativo possa ser visto por trs dele.
A anterior mensagem de aplicao MI tambm fornece um exemplo de um uso
interessante da imeOptions, para especificar a ao de envio, mas no que seja mostrado
a tecla Enter:
android:imeOptions="actionSend|flagNoEnterAction"
APIs para controlar IMEs
Para um controle mais avanado sobre o IME, h uma variedade de novas APIs que
voc pode usar. A menos que tenha um cuidado especial (como por meio de reflexo),
utilizando essas APIs far com que seu aplicativo seja incompatvel com as verses
anteriores do Android, e voc deve se certificar de que voc especifique
android:minSdkVersion="3" em seu manifesto.
A API principal o novo android.view.inputmethod.InputMethodManager, que voc
pode recuperar com Context.getSystemService(). Ele permite que voc interaja com o
estado global do mtodo de entrada, como explicitamente esconder ou mostrar a rea
atual do IME de entrada.
ANDROID, uma viso geral Anderson Duarte de Amorim
223
H tambm novas bandeiras controlando a interao do mtodo de entrada, que voc
pode controlar atravs da existente Window.addFlags() e novos
Window.setSoftInputMode(). A classe PopupWindow acrescentou mtodos
correspondentes para controlar essas opes em sua janela. Uma coisa em particular a
ter em conta o novo
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, que usado para
controlar se uma janela est em cima ou atrs do IME atual.
A maior parte da interao entre um IME ativos e a aplicao feita atravs do
android.view.inputmethod.InputConnection. Esta a API implementada em uma
aplicao, que um IME chama para realizar as operaes de edio apropriada sobre o
pedido. Voc no vai precisar se preocupar com isso, pois TextView oferece sua prpria
implementao para si mesmo.
H tambm um punhado de novas View s APIs, a mais importante delas sendo
onCreateInputConnection() que cria um novo InputConnection de um IME (e preenche
um android.view.inputmethod.EditorInfo com o seu tipo de entrada, as opes IME, e
outros dados), novamente, a maioria dos desenvolvedores no precisaro se preocupar
com isso, pois TextView cuida disso para voc.
Criando um mtodo de entrada de dados
Para criar um mtodo de entrada (IME) para inserir texto em campos de texto e outras
exibies, voc precisa estender a classe InputMethodService. Essa classe fornece
grande parte da implementao de base para um mtodo de entrada, em termos de
administrar o estado e a visibilidade do mtodo de entrada e se comunicar com a
atividade visvel no momento.
O tpico ciclo de vida de um InputMethodService:
ANDROID, uma viso geral Anderson Duarte de Amorim
224

ANDROID, uma viso geral Anderson Duarte de Amorim
225
Campos de um aplicativo de texto podem ter diferentes tipos de entrada especificada
sobre eles, como o texto de forma livre, numrico, URL, endereo de e-mail e busca.
Quando voc implementa um novo mtodo de entrada, voc precisa estar ciente dos
tipos de entrada diferentes. Os mtodos de entrada no so automaticamente comutados
para diferentes tipos de entrada e por isso necessrio para suportar todos os tipos no
IME. No entanto, o IME no responsvel por validar a entrada enviada para o
aplicativo. Essa a responsabilidade da aplicao.
Por exemplo, o LatinIME equipados com a plataforma Android oferece layouts
diferentes para o texto e entrada de nmero de telefone:

Preste ateno especfica ao enviar o texto para campos de senha. Certifique-se que a
senha no visvel na sua interface do usurio - nem no modo de exibio de entrada ou
o ponto de vista dos candidatos. Alm disso, no salvar a senha em qualquer lugar sem
explicitamente informar o utilizador.
A interface do usurio deve ser capaz de escala entre as orientaes retrato e paisagem.
No modo IME no fullscreen, deixar espao suficiente para a aplicao para mostrar o
campo de texto e qualquer contexto associado. De preferncia, no mais que metade da
tela deve ser ocupada pelo IME.
Existem duas maneiras de enviar mensagens de texto para o aplicativo. Voc pode
enviar individuais eventos-chave ou voc pode editar o texto ao redor do cursor no
campo a aplicao do texto.
Para enviar um evento-chave, voc pode simplesmente construir objetos KeyEvent e
chamar InputConnection.sendKeyEvent(). Aqui esto alguns exemplos:
InputConnection ic = getCurrentInputConnection();
long eventTime = SystemClock.uptimeMillis();
ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
ANDROID, uma viso geral Anderson Duarte de Amorim
226
KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0,
KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0,
KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
Ou ento use o seguinte comando:
InputMethodService.sendDownUpKeyEvents(keyEventCode);
Ao editar texto em um campo de texto, alguns dos mtodos mais teis na
android.view.inputmethod.InputConnection so:
getTextBeforeCursor()
getTextAfterCursor()
deleteSurroundingText()
commitText()
Aes de desenhos
Drawable Mutations uma classe para oferecer ao programador algo que pode ser
desenhado (Drawable Mutations).
Por exemplo, um BitmapDrawable usado para exibir imagens, um ShapeDrawable
para desenhar formas e gradientes e assim por diante. Voc pode at mesmo combin-
las para criar renderizaes complexas.
Por exemplo, toda vez que voc criar um Button, uma nova drawable carregada a
partir do quadro de recursos ( android.R.drawable.btn_default ). Isto significa que todos
os botes em todos os aplicativos usam uma instncia diferente drawable como pano de
fundo. No entanto, todas estas partes drawables possuem um estado comum, o
chamado "estado constante". O contedo deste estado varia de acordo com o tipo de
drawable voc est usando, mas, geralmente, contm todas as propriedades que podem
ser definidos por um recurso. No caso de um boto, o constante estado contm uma
imagem bitmap. Desta forma, todos os botes em todos os aplicativos compartilham o
mesmo bitmap, o que economiza um monte de memria.
O diagrama abaixo mostra como as entidades so criadas quando voc atribuir o
recurso de mesma imagem como fundo de dois pontos de vista diferentes. Como voc
ANDROID, uma viso geral Anderson Duarte de Amorim
227
pode ver dois drawables so criadas, mas que ambos compartilham o mesmo estado
constante, portanto, a mesma bitmap:

Esse recurso de compartilhamento de estado de grande valia para evitar o desperdcio
de memria, mas pode causar problemas quando voc tentar modificar as propriedades
de um drawable. Imagine uma aplicao com uma lista de livros. Cada livro tem uma
estrela ao lado de seu nome, totalmente opaco quando o usurio marca o livro como um
dos favoritos, e translcido quando o livro no um favorito. Para conseguir esse
efeito, voc provavelmente vai escrever o seguinte cdigo em seu mtodo adaptador de
lista do getView():
Book = ...;
TextView Item_da_lista = ...;

listItem.setText (book.getTitle ());

estrela Drawable = context.getResources () getDrawable (R.drawable.star).;
if (book.isFavorite ()) {
star.setAlpha (255); / opaca /
Else {}
star.setAlpha (70); / translcido
}
ANDROID, uma viso geral Anderson Duarte de Amorim
228
Infelizmente, este pedao de cdigo gera um resultado um pouco estranho: todas as
drawables tm a mesma opacidade. Esse resultado explicado pela constante estado.
Mesmo que ns estamos comeando uma nova instncia drawable para cada item da
lista, o constante estado permanece o mesmo e, no caso de BitmapDrawable, a
opacidade parte da constante estado. Assim, mudando a opacidade de uma instncia
muda drawable a opacidade de todas as outras instncias.
Android 1.5 e superior oferecem uma maneira muito fcil de resolver esse problema
com a nova mutate() mtodo. Quando voc chamar esse mtodo em um drawable, a
constante estado de drawable duplicada para permitir a voc alterar qualquer
propriedade, sem afetar outros drawables. Note-se que os bitmaps so ainda comuns,
mesmo depois de uma mutao drawable. O diagrama abaixo mostra o que acontece
quando voc chama mutate() em um drawable:

ANDROID, uma viso geral Anderson Duarte de Amorim
229
Agora, o cdigo a ser escrito parecido com o abaixo.
Drawable star = context.getResources().getDrawable(R.drawable.star);
if (book.isFavorite()) {
star.mutate().setAlpha(255); // opaque
} else {
star. mutate().setAlpha(70); // translucent
}
Assim, um exemplo se uso, como o citado acerca dos livros, fica como a figura abaixo.

Truques de layout: criando layouts eficientes
O Android UI Toolkit oferece diversos gerenciadores de layout que so bastante fceis
de usar e, na maioria das vezes, voc s precisa das caractersticas bsicas destes
gerenciadores de layout para implementar uma interface de usurio.
Ater-se s caractersticas bsicas infelizmente no a forma mais eficiente para criar
interfaces de usurio. Um exemplo comum o abuso de LinearLayout , o que leva a
uma proliferao de pontos de vista e hierarquia de vista. Cada ponto de vista - ou pior,
cada gerente de layout - que voc adicionar sua aplicao tem um custo: layout de
inicializao, e o desenho se torna mais lento. A passagem de layout pode ser muito
ANDROID, uma viso geral Anderson Duarte de Amorim
230
cara principalmente quando voc aninhar diversos LinearLayout que utilizam o weight
do parmetro, que requer que o nodo filho seja medido duas vezes.
Consideremos um exemplo muito simples e comum de um esquema: um item da lista
com um cone no lado esquerdo, um ttulo em cima e uma descrio opcional abaixo do
ttulo.

Uma ImageView e dois TextView so posicionados em relao uns aos outros, aqui o
wireframe do layout como capturado pelos HierarchyViewer :

A implementao desta estrutura simples com LinearLayout. O item em si uma
LinearLayout horizontal com um ImageView e um LinearLayout vertical, que contm
as duas TextView. Aqui est o cdigo fonte deste esquema:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"

android:padding="6dip">

<ImageView
android:id="@+id/icon"

android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="6dip"

android:src="@drawable/icon" />

<LinearLayout
android:orientation="vertical"

android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">

<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
ANDROID, uma viso geral Anderson Duarte de Amorim
231
android:layout_weight="1"

android:gravity="center_vertical"
android:text="My Application" />

<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"

android:singleLine="true"
android:ellipsize="marquee"
android:text="Simple application that shows how to use RelativeLayout" />

</LinearLayout>

</LinearLayout>
Este esquema acima funciona, mas pode ser prejudicial se voc instanci-la para cada
item da lista de um ListView . O mesmo esquema pode ser reescrito utilizando um
nico RelativeLayout , salvando assim um ponto de vista, e melhor ainda, um nvel na
hierarquia do ponto de vista, por item da lista. A implementao do layout com um
RelativeLayout simples:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"

android:padding="6dip">

<ImageView
android:id="@+id/icon"

android:layout_width="wrap_content"
android:layout_height="fill_parent"

android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="6dip"

android:src="@drawable/icon" />

<TextView
android:id="@+id/secondLine"

android:layout_width="fill_parent"
android:layout_height="26dip"

android:layout_toRightOf="@id/icon"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"

ANDROID, uma viso geral Anderson Duarte de Amorim
232
android:singleLine="true"
android:ellipsize="marquee"
android:text="Simple application that shows how to use RelativeLayout" />

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"

android:layout_toRightOf="@id/icon"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@id/secondLine"
android:layout_alignWithParentIfMissing="true"

android:gravity="center_vertical"
android:text="My Application" />

</RelativeLayout>
Esta nova aplicao se comporta exatamente da mesma forma que a implementao
anterior, exceto em um caso: o item da lista que se pretende apresentar tem duas linhas
de texto: o ttulo e uma descrio opcional. Quando uma descrio no est disponvel
para um determinado item da lista o aplicativo simplesmente define a visibilidade do
segundo TextView como GONE. Isso funciona perfeitamente com o LinearLayout, mas
no com o RelativeLayout:


Em um RelativeLayout, as vistas so alinhadas com a sua me, com o
RelativeLayout em si, ou com outras vises. Por exemplo, ns declaramos que a
descrio est alinhado com a parte inferior da RelativeLayout e que o ttulo
colocado acima da descrio e ancorado a me da top. Com a descrio GONE, o
RelativeLayout no sabe a posio da margem inferior do ttulo. Para resolver esse
problema, voc pode usar um parmetro muito especial chamado
layout_alignWithParentIfMissing.
Este parmetro boolean simplesmente diz ao RelativeLayout a utilizar os seus prprios
limites como ncoras quando um alvo est faltando. Por exemplo, se voc posicionar
uma view direita de uma GONE e definir alignWithParentIfMissing como true,
ANDROID, uma viso geral Anderson Duarte de Amorim
233
RelativeLayout vez vai ancorar o fim de sua borda esquerda. No nosso caso, usando
alignWithParentIfMissing far RelativeLayout alinhar a parte inferior do ttulo
com si mesmo. O resultado o seguinte:


O comportamento do nosso layout est perfeito, mesmo quando a descrio GONE.
Ainda melhor, a hierarquia mais simples porque no estamos usando pesos
LinearLayout's tambm mais eficiente. A diferena entre as duas implementaes
torna-se evidente quando se comparam as hierarquias em HierarchyViewer:

ANDROID, uma viso geral Anderson Duarte de Amorim
234
Truques de layout: usando ViewStub
Compartilhamento e reutilizao de componentes de interface do usurio so muito
fceis com o Android, graas tag <include/>. s vezes to fcil criar complexas
construes UI que UI termina com um grande nmero de pontos de vista, algumas das
quais raramente so utilizados. Felizmente, o Android oferece um widget muito especial
chamado ViewStub , que traz todos os benefcios da <include /> sem poluir a interface
do usurio com views raramente utilizadas.
A ViewStub uma viso leve. No tem dimenso, no tira nada e no participa no
layout de qualquer forma. Isso significa que uma ViewStub muito barata para inflar e
muito barata para se manter em uma hierarquia de vista. A ViewStub pode ser melhor
descrita como um preguioso <include />. O esquema referenciado por um ViewStub
inflado e adicionado interface do usurio somente quando assim o decidir.
A figura a seguir vem da aplicao Prateleira. O principal objetivo da atividade
mostrado na imagem apresentar ao usurio uma lista pesquisvel dos livros:

ANDROID, uma viso geral Anderson Duarte de Amorim
235
A atividade tambm usada quando o usurio adiciona ou importa novos livros.
Durante essa operao, a Prateleira mostra bits adicionais de interface do usurio. A
imagem abaixo mostra a barra de progresso e um boto cancelar que aparecer na parte
inferior da tela durante uma importao:

Como a importao de livros no uma operao comum, pelo menos quando
comparado visita a lista de livros, o painel de importao representado inicialmente
por um ViewStub :
ANDROID, uma viso geral Anderson Duarte de Amorim
236

Quando o usurio inicia o processo de importao, o ViewStub inflado e passa a ter o
contedo do arquivo de layout que faz referncia:

ANDROID, uma viso geral Anderson Duarte de Amorim
237
Para usar um ViewStub , tudo que voc precisa especificar um atributo android:id,
para depois inflar, e um atributo android:layout para fazer referncia ao arquivo de
layout para incluir e inflar. Um stub permite que voc use um terceiro atributo,
android:inflatedId , que pode ser usado para substituir o id da raiz do arquivo includo.
Finalmente, os parmetros de layout especificados no topo sero aplicados para a raiz
do layout includo. Aqui est um exemplo:
<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"

android:layout="@layout/progress_overlay"

android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
Quando estiver pronto para inflar o stub, basta invocar o mtodo inflate(). Voc tambm
pode simplesmente alterar a visibilidade do stub para VISIBLE ou INVISIBLE e o stub
ir inflar. Note, no entanto que o mtodo inflate() tem a vantagem de retornar a raiz
View ao inflar o layout:
((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
muito importante lembrar que aps o stub ser inflado, o topo removido da hierarquia
de vista. Como tal, necessrio manter uma referncia de vida longa, por exemplo, em
um campo de instncia de classe, a uma ViewStub .
Um ViewStub um grande compromisso entre a facilidade de programao e de
eficincia. Em vez de encher vistas manualmente e adicion-los em tempo de execuo
de sua hierarquia de vista, basta usar um ViewStub. barato e fcil. A nica
desvantagem de ViewStub que atualmente no suporta a tag <merge />.
Truques de layout: mesclando layouts
A tag <merge /> foi criada com a finalidade de otimizar layouts Android, reduzindo o
nmero de nveis em rvores de vista. mais fcil entender o problema que esta tag
resolve olhando um exemplo. O esquema XML a seguir declara um layout que mostra
uma imagem com o ttulo em cima dela. A estrutura bastante simples, uma
FrameLayout usada para empilhar um TextView em cima de um ImageView :
ANDROID, uma viso geral Anderson Duarte de Amorim
238
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:scaleType="center"
android:src="@drawable/golden_gate" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"

android:padding="12dip"

android:background="#AA000000"
android:textColor="#ffffffff"

android:text="Golden Gate" />

</FrameLayout>
Isso torna o layout bem e nada parece errado com ele:

ANDROID, uma viso geral Anderson Duarte de Amorim
239
As coisas ficam mais interessantes quando voc inspecionar o resultado com
HierarchyViewer. Se voc olhar atentamente para a rvore resultante, voc vai notar
que o FrameLayout definida no arquivo XML (destacada em azul abaixo) o filho
nico de outro FrameLayout:

S fizemos a interface mais complexa, sem qualquer razo. Mas como poderamos nos
livrar do presente FrameLayout? Afinal de contas, documentos XML requerem uma
marca de raiz e tags em esquemas XML sempre representam instncias.
a que o <merge /> vem a calhar. Quando o LayoutInflater encontra essa marca, ele
ignora-o e adiciona o <merge /> dos nodos ao <merge /> pai. Confuso? Vamos
reescrever o nosso layout XML anterior, substituindo o FrameLayout com <merge />:
ANDROID, uma viso geral Anderson Duarte de Amorim
240
<merge xmlns:android="http://schemas.android.com/apk/res/android">

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:scaleType="center"
android:src="@drawable/golden_gate" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"

android:padding="12dip"

android:background="#AA000000"
android:textColor="#ffffffff"

android:text="Golden Gate" />

</merge>
Com esta nova verso, tanto o TextView quanto o ImageView sero adicionados
diretamente ao nvel superior. O resultado ser o mesmo, mas visualmente a hierarquia
do ponto de vista simples:

ANDROID, uma viso geral Anderson Duarte de Amorim
241
Obviamente, o uso do <merge /> funciona neste caso porque o nodo pai sempre um
FrameLayout. Voc no pode aplicar este truque se o layout estava usando um
LinearLayout como sua marca raiz, por exemplo. O <merge /> pode ser til em outras
situaes, no entanto. Por exemplo, ele funciona perfeitamente quando combinado com
o <include />. Voc tambm pode usar <merge /> quando voc cria um composto de
exibio personalizado. Vamos ver como podemos usar essa tag para criar uma nova
viso chamada OkCancelBar que simplesmente mostra dois botes com rtulos
personalizados.
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge">

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:scaleType="center"
android:src="@drawable/golden_gate" />

<com.example.android.merge.OkCancelBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"

android:paddingTop="8dip"
android:gravity="center_horizontal"

android:background="#AA000000"

okCancelBar:okLabel="Save"
okCancelBar:cancelLabel="Don't save" />

</merge>
ANDROID, uma viso geral Anderson Duarte de Amorim
242

O cdigo fonte do OkCancelBar muito simples, porque os dois botes so definidos
em um arquivo XML externo, carregado com um LayoutInflate. Como voc pode ver
no trecho a seguir, o esquema XML R.layout.okcancelbar inflado com o OkCancelBar
como o pai:
public class OkCancelBar extends LinearLayout {
public OkCancelBar(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER);
setWeightSum(1.0f);

LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);

String text = array.getString(R.styleable.OkCancelBar_okLabel);
if (text == null) text = "Ok";
((Button) findViewById(R.id.okcancelbar_ok)).setText(text);

text = array.getString(R.styleable.OkCancelBar_cancelLabel);
if (text == null) text = "Cancel";
((Button) findViewById(R.id.okcancelbar_cancel)).setText(text);
ANDROID, uma viso geral Anderson Duarte de Amorim
243

array.recycle();
}
}
Os dois botes so definidos no esquema XML a seguir. Como voc pode ver, usamos
o <merge /> para adicionar os dois botes diretamente ao OkCancelBar . Cada boto
est includo a partir do arquivo XML externo mesmo layout para torn-los mais fceis
de manter, ns simplesmente substituimos o seu id:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<include
layout="@layout/okcancelbar_button"
android:id="@+id/okcancelbar_ok" />

<include
layout="@layout/okcancelbar_button"
android:id="@+id/okcancelbar_cancel" />
</merge>
Ns criamos uma forma flexvel e fcil de manter a exibio personalizada que gera
uma hierarquia de vista eficiente:

ANDROID, uma viso geral Anderson Duarte de Amorim
244
O <merge /> extremamente til e pode fazer maravilhas em seu cdigo. No entanto,
ele sofre de um par de limitaes:
<merge /> s pode ser usado como a tag raiz de um esquema XML
Ao inflar um layout comeando com uma <merge /> voc deve especificar um
pai ViewGroup e voc deve definir attachToRoot como true
ListView, uma otimizao
ListView um dos widgets mais amplamente utilizados no Android. bastante fcil de
usar, muito flexvel e incrivelmente poderoso.
Um dos problemas mais comuns com ListView acontece quando voc tenta usar um
plano personalizado. Por padro, como muitos widgets do Android, o ListView tem um
fundo transparente, o que significa que voc pode ver atravs do padro da janela do
fundo. Alm disso, ListView permite as margens de desvanecimento por padro, como
voc pode ver no topo da tela a seguir - o texto do primeiro item desvanece-se
gradualmente para preto. Esta tcnica utilizada em todo o sistema para indicar que o
continer pode ser rolado.

ANDROID, uma viso geral Anderson Duarte de Amorim
245
O efeito de fade implementado usando uma combinao de Canvas.saveLayerAlpha()
e Porter-Duff Destination Out blending mode.
Infelizmente, as coisas comeam a ficarem feias quando voc tenta usar um background
personalizado no ListView ou quando voc muda a janela de fundo. A seguir duas
imagens mostram o que acontece em um aplicativo quando voc mudar o fundo da
janela. A imagem da esquerda mostra como a lista se parece por padro e a imagem da
direita mostra o como a lista se parece durante um deslocamento iniciado com um gesto
de tocar:

Este problema de processamento causada por uma otimizao do quadro Android
ativada por padro em todas as instncias do ListView. Esta aplicao funciona muito
bem, mas infelizmente muito caro e pode trazer para baixo o desempenho de desenho,
um pouco como ele necessita para capturar uma parcela da prestao em um bitmap fora
da tela e, em seguida, requer a mistura extra (o que implica readbacks da memria).
ListViews so, na maioria das vezes exibidos em uma base slida, no h nenhuma
razo para enveredar por esse caminho caro. por isso que ns introduzimos uma
otimizao chamada de pitada de cor cache. A dica de cor cache uma cor RGB
definido por padro com a cor de fundo da janela, que #191919 no tema escuro do
ANDROID, uma viso geral Anderson Duarte de Amorim
246
Android. Quando esta dica definida, ListView (na verdade, sua classe base View) sabe
que vai recorrer a um fundo slido e substitui, portanto, a cara renderizao
saveLayerAlpha()/Porter-Duff por um gradiente simples. Este gradiente vai desde
totalmente transparente para o valor de cor cache e exatamente isso que voc v na
imagem acima, com o gradiente escuro na parte inferior da lista. No entanto, isso ainda
no explica por que a lista inteira fica em preto durante um pergaminho.
Como mencionado anteriormente, ListView tem um fundo transparente/translcido por
padro, assim como todos os widgets padro na caixa de ferramentas UI Android. Isto
implica que, quando ListView redesenha seus filhos, tem que misturar as crianas com
janela de fundo. Mais uma vez, isto requer readbacks caros de memria que so
particularmente dolorosos durante um deslocamento ou uma aventura, quando acontece
o desenho dezenas de vezes por segundo.
Para melhorar o desempenho de desenho durante as operaes de rolagem, o quadro
Android reutiliza a dica de cor cache.
Para corrigir esse problema, tudo que voc tem que fazer desativar o cache de
otimizao de cor, se voc usar uma cor de fundo no-contnua, ou definir a dica para o
valor de cor slido adequado. Voc pode fazer isso a partir do cdigo ou, de preferncia,
a partir de XML, usando o android:cacheColorHint. Para desabilitar a otimizao, basta
usar a cor transparente #00000000. A figura abaixo mostra uma lista com
android:cacheColorHint="#00000000" definido no arquivo de layout XML:

ANDROID, uma viso geral Anderson Duarte de Amorim
247
Como voc pode ver, o fade funciona perfeitamente contra o fundo personalizado em
madeira. O recurso de cache de sugesto de cor interessante porque mostra como as
otimizaes podem tornar sua vida mais difcil em algumas situaes. Neste caso
especfico, porm, o benefcio do comportamento padro compensa a maior
complexidade.
Live folders
Live Folders, introduzida no Android 1.5 API (Nvel 3), permitem a exibio de
qualquer fonte de dados na tela inicial, sem forar o usurio a lanar uma aplicao.
Uma live folder simplesmente uma viso em tempo real de um ContentProvider.
Como tal, uma live folder pode ser usada para exibir todos os contatos do usurio ou
bookmarks, e-mail, listas de reproduo, um feed RSS, e assim por diante. As
possibilidades so infinitas!
A plataforma inclui vrias pastas padro para a exibio de contatos. Por exemplo, a
imagem abaixo mostra o contedo das pastas ao vivo que mostra todos os contatos com
um nmero de telefone:

ANDROID, uma viso geral Anderson Duarte de Amorim
248
Se a sincronizao de contatos acontece em segundo plano enquanto o usurio est
visitando esta pasta ao vivo, o usurio ver a mudana acontecer em tempo real. Live
folders no so apenas teis, mas elas tambm so fceis de adicionar ao seu aplicativo.
Este artigo mostra como adicionar uma live folder para uma aplicao, como por
exemplo as chamadas Prateleiras. Para entender melhor como trabalham as pastas, voc
pode baixar o cdigo fonte da aplicao e modific-lo seguindo as instrues abaixo.
Para dar ao usurio a opo de criar uma nova pasta para um aplicativo, voc primeiro
precisa criar uma nova atividade com a inteno de filtro cuja ao
android.intent.action.CREATE_LIVE_FOLDER. Para isso, basta abrir
AndroidManifest.xml e adicionar algo semelhante a isto:
<activity
android:name=".activity.BookShelfLiveFolder"
android:label="BookShelf">
<intent-filter>
<action android:name="android.intent.action.CREATE_LIVE_FOLDER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
O rtulo e o cone desta atividade so o que o usurio ver na tela inicial quando se
escolhe uma pasta:

ANDROID, uma viso geral Anderson Duarte de Amorim
249
Uma vez que voc s precisa de uma inteno de filtro, possvel e, por vezes
aconselhvel, a reutilizao de uma atividade existente. No caso de Prateleiras, vamos
criar uma nova atividade,
org.curiouscreature.android.shelves.activity.BookShelfLiveFolder. O papel desta
atividade enviar um resultado Intent para Pgina contendo a descrio da live folder: o
seu nome, cone, modo de apresentao e contedo URI. O URI contedo muito
importante, pois descreve o que ContentProvider ser usado para preencher a live
folder. O cdigo da atividade muito simples, como voc pode ver aqui:
public class BookShelfLiveFolder extends Activity {
public static final Uri CONTENT_URI = Uri.parse("content://shelves/live_folders/books");

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

final Intent intent = getIntent();
final String action = intent.getAction();

if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
setResult(RESULT_OK, createLiveFolder(this, CONTENT_URI,
"Books", R.drawable.ic_live_folder));
} else {
setResult(RESULT_CANCELED);
}

finish();
}

private static Intent createLiveFolder(Context context, Uri uri, String name, int icon) {
final Intent intent = new Intent();

intent.setData(uri);
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, name);
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON,
Intent.ShortcutIconResource.fromContext(context, icon));
intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
LiveFolders.DISPLAY_MODE_LIST);

return intent;
}
}
Esta atividade, quando invocada com a ACTION_CREATE_LIVE_FOLDER, retorna
com a inteno de um URI, content://shelves/live_folders/books , e trs extras para
descrever a pasta ao vivo. Existem outros extras e constantes que voc pode usar e voc
deve consultar a documentao do android.provider.LiveFolders para mais detalhes.
ANDROID, uma viso geral Anderson Duarte de Amorim
250
Quando a Home recebe esta ao, uma nova live folder criada no desktop do usurio,
com o nome e o cone que voc forneceu. Ento, quando o usurio clica na pasta para
abri-la ao vivo, a Home consulta o provedor de contedo referenciado pelo URI
fornecido.
Prestadores de pastas Live devem obedecer a regras especficas de nomeao. O Cursor
retornado pelo mtodo query() deve ter pelo menos duas colunas chamadas
LiveFolders._ID e LiveFolders.NAME . O primeiro o identificador nico de cada item
na live folder e o segundo o nome do item. H nomes de coluna que voc pode usar
para especificar um cone, uma descrio, a inteno de associar ao item (acionado
quando o usurio clicar nesse item), etc. Novamente, consulte a documentao do
android.provider.LiveFolders para mais detalhes .
No nosso exemplo, tudo o que precisamos fazer modificar o provedor existente nas
prateleiras chamado org.curiouscreature.android.shelves.provider.BooksProvider.
Primeiro, precisamos modificar o URI_MATCHER para reconhecer nosso
content://shelves/live_folders/books URI de contedo:
private static final int LIVE_FOLDER_BOOKS = 4;
// ...
URI_MATCHER.addURI(AUTHORITY, "live_folders/books", LIVE_FOLDER_BOOKS);
Ento, precisamos criar um mapa de nova projeo para o cursor. Um mapa de
projeo pode ser usado para "renomear" colunas. No nosso caso, vamos substituir
BooksStore.Book._ID , BooksStore.Book.TITLE e BooksStore.Book.AUTHORS com
LiveFolders._ID , LiveFolders.TITLE e LiveFolders.DESCRIPTION:
private static final HashMap<string, string=""> LIVE_FOLDER_PROJECTION_MAP;
static {
LIVE_FOLDER_PROJECTION_MAP = new HashMap<string, string="">();
LIVE_FOLDER_PROJECTION_MAP.put(LiveFolders._ID, BooksStore.Book._ID +
" AS " + LiveFolders._ID);
LIVE_FOLDER_PROJECTION_MAP.put(LiveFolders.NAME, BooksStore.Book.TITLE +
" AS " + LiveFolders.NAME);
LIVE_FOLDER_PROJECTION_MAP.put(LiveFolders.DESCRIPTION,
BooksStore.Book.AUTHORS +
" AS " + LiveFolders.DESCRIPTION);
}
Porque estamos a dar um ttulo e uma descrio para cada linha, Home ir exibir
automaticamente cada item da live folder com duas linhas de texto. Finalmente, vamos
ANDROID, uma viso geral Anderson Duarte de Amorim
251
implementar a query(), fornecendo o nosso mapa de projeo para o construtor de
consultas SQL:
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {

SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

switch (URI_MATCHER.match(uri)) {
// ...
case LIVE_FOLDER_BOOKS:
qb.setTables("books");
qb.setProjectionMap(LIVE_FOLDER_PROJECTION_MAP);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}

SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null,
BooksStore.Book.DEFAULT_SORT_ORDER);
c.setNotificationUri(getContext().getContentResolver(), uri);

return c;
}
Agora voc pode compilar e implantar o aplicativo, v para a tela inicial e tente
adicionar uma live folder. Voc pode adicionar uma pasta para os livros na sua tela
inicial e quando voc abri-lo, veja a lista de todos os seus livros, com seus ttulos e
autores, e bastou algumas linhas de cdigo:

ANDROID, uma viso geral Anderson Duarte de Amorim
252
A API de live folders extremamente simples e depende apenas de intenes e URI. Se
voc quiser ver mais exemplos de aplicao das pastas, voc pode ler o cdigo-fonte do
aplicativo de contatos e do provedor de Contatos.
Live Wallpapers
Comeando com o Android 2.1 (API Nvel 7), os utilizadores podem agora desfrutar de
papis de parede ao vivo - mais ricos, animados, cenrios interativos - em suas telas
iniciais. Um papel de parede ao vivo muito semelhante a uma aplicao Android
normal e tem acesso a todas as facilidades da plataforma: SGL (desenho 2D), OpenGL
(desenho 3D), GPS, acelermetro, acesso rede, etc. Os papis de parede ao vivo,
includo no Nexus One, demonstram o uso de algumas dessas APIs para criar
experincias divertidas e interessantes. Por exemplo, o papel de parede da grama usa a
localizao do telefone para calcular o nascer e o por do sol, a fim de exibir o cu
adequado.

Criar o seu prprio papel de parede ao vivo fcil, especialmente se voc teve
experincia anterior com SurfaceView ou Canvas. Para saber como criar um papel de
parede ao vivo, voc deve verificar se o cdigo de exemplo CubeLiveWallpaper .
Em termos de execuo, um papel de parede ao vivo muito similar a um Service. A
nica diferena a adio de um novo mtodo, onCreateEngine(), cujo objetivo criar
um WallpaperService.Engine. O dispositivo responsvel pela gesto do ciclo de vida e
desenho de um papel de parede. O sistema fornece uma superfcie sobre a qual voc
pode desenhar, assim como voc faria com um SurfaceView. Desenho de um papel de
parede pode ser muito caro por isso voc deve otimizar o cdigo, tanto quanto possvel
para evitar o uso excessivo de CPU, no s para a vida da bateria, mas tambm para
evitar a abrandar o resto do sistema. tambm por isso que a parte mais importante do
ciclo de vida de um papel de parede quando se torna visvel, como indicado por uma
ANDROID, uma viso geral Anderson Duarte de Amorim
253
chamada para onVisibilityChanged(). Quando invisveis, como quando o usurio inicia
um aplicativo que cobre a tela inicial, o papel de parede tem que parar todas as
atividades.
O dispositivo tambm pode implementar vrios mtodos para interagir com o usurio
ou o aplicativo de origem. Por exemplo, para reagir ao toque, basta implementar
onTouchEvent(). Finalmente, os aplicativos podem enviar comandos arbitrrios para o
papel de parede ao vivo. Atualmente, apenas o pedido inicial padro envia comandos
para o onCommand() do papel de parede ao vivo:
1. android.wallpaper.tap: Quando o usurio bate um espao vazio na rea de
trabalho. Este comando interpretado pelo dispositivo para fazer o papel de
parede reagir interao do usurio.
2. android.home.drop: Quando o usurio solta um cone ou um widget no espao
de trabalho.
Se voc est desenvolvendo um papel de parede ao vivo, lembre-se que o recurso s
suportado no Android 2.1 (API nvel 7) e verses superiores da plataforma. Para
garantir que seu pedido s pode ser instalado em dispositivos que suportam wallpapers,
lembre-se de acrescentar o seguinte trecho de cdigo antes de publicar no Android
Market:
<uses-sdk android:minSdkVersion="7" />, que indica Android Market e
plataforma que seu aplicativo requer Android 2.1 ou superior.
<uses-feature android:name="android.software.live_wallpaper" />, que informa
Android Market que seu aplicativo inclui um papel de parede ao vivo. Android
Market usa esse recurso como um filtro, ao apresentar listas de usurios de
aplicaes disponveis. Quando voc declarar esse recurso, o Android Market
exibe sua aplicao apenas aos usurios cujas dispositivos suportam wallpapers
ao vivo, enquanto oculta de outros dispositivos sobre os quais no seria capaz de
executar.
ANDROID, uma viso geral Anderson Duarte de Amorim
254
Usando webViews
Um pequeno aplicativo chamado WebViewDemo mostra como voc pode adicionar
contedo da Web em seu aplicativo. Voc pode encontr-la no projeto de aplicativos
para Android. Esta aplicao demonstra como voc pode incorporar um WebView em
uma atividade e tambm como voc pode ter comunicao bidirecional entre o
aplicativo e o contedo da web.
Um WebView utiliza o mesmo processamento e motor de JavaScript, o navegador, mas
ele executado sob o controle de sua aplicao. O WebView podem ser em tela cheia
ou voc pode mistur-la com outras vises. O WebView pode baixar contedo da web,
ou pode vir a partir de arquivos locais armazenados em seu diretrio de ativos. O
contedo pode at ser gerado dinamicamente pelo cdigo do aplicativo.
Este aplicativo no faz muita coisa: quando voc clica sobre o Android, ele levanta o
brao.

Isso poderia, naturalmente, ser facilmente conseguido com um pouco de JavaScript.
Em vez disso, porm, WebViewDemo toma um caminho um pouco mais complicado
para ilustrar duas caractersticas muito poderosa de WebView.
Primeiro, o JavaScript em execuo dentro do WebView pode se ligar com o cdigo em
sua atividade. Voc pode usar isso para fazer suas aes disparar JavaScript como
comear uma nova atividade, ou pode ser usada para buscar dados de um banco de
dados ou ContentProvider . A API para isso muito simples: basta conectar com o
addJavascriptInterface()em sua WebView. Voc passa um objeto cujos mtodos voc
ANDROID, uma viso geral Anderson Duarte de Amorim
255
deseja expor ao JavaScript e o nome a ser usado para fazer chamadas. Voc pode ver a
sintaxe exata em WebViewDemo.java. Aqui ns estamos fazendo o nosso objeto
DemoJavascriptInterface disponvel em JavaScript para onde ele vai ser chamado de
"window.demo".
Em segundo lugar, sua atividade pode invocar mtodos JavaScript. Tudo que voc tem a
fazer chamar o mtodo loadUrl com a chamada de JavaScript apropriada:
mWebView.loadUrl("javascript:wave()");
Nosso WebViewDemo utiliza duas tcnicas: quando voc clica sobre o Android, que
chama a atividade, que ento se vira e chama de volta para o JavaScript. WebViews so
muito poderosos e podem ser uma ferramenta valiosa para ajudar a construir a sua
aplicao - especialmente se voc j tem um monte de contedo HTML. Quando isso
acontece, usamos exatamente essa abordagem em algumas das aplicaes que ns
escrevemos.
Funcionalidades
Caixa de pesquisa
Comeando com o Android 1.6, a plataforma inclui suporte para caixa de pesquisa
rpida (CPR ou QSB Quick Search Box), uma poderosa estrutura de pesquisa de todo o
sistema. A caixa de pesquisa rpida permite que os usurios rapidamente e facilmente
encontrem o que procuram, tanto em seus dispositivos quanto na web. Ele sugere
contedo no seu dispositivo enquanto voc digita como aplicativos, contatos, histrico
do navegador, e msica. Tambm oferece resultados das sugestes de pesquisa na web,
anncios de empresas locais e outras informaes do Google, tais como cotaes da
bolsa, previso do tempo e status de vo. Tudo isso est disponvel logo na tela inicial,
tocando na caixa de pesquisa rpida.
Seus aplicativos podem fornecer sugestes de pesquisa que surgiro a usurios de CPR
junto com outros resultados de pesquisa e sugestes. Isso torna possvel para os usurios
acessem o contedo do seu aplicativo de fora da sua aplicao, por exemplo, a partir da
tela inicial.
ANDROID, uma viso geral Anderson Duarte de Amorim
256
Nota: Os fragmentos de cdigo deste documento esto relacionados a um aplicativo de
exemplo chamado Dicionrio pesquisvel. O aplicativo est disponvel para o Android
1.6 e plataformas posteriores.
Plataforma de lanamentos de verses anteriores para o Android 1.6 j previam um
mecanismo que permite que voc exponha pesquisa e sugestes de busca na sua
aplicao, conforme descrito na documentao para SearchManager. Esse mecanismo
no mudou e exige as seguintes coisas em sua AndroidManifest.xml :
1. Em sua <activity>, a inteno do filtro, e uma referncia a um searchable.xml
arquivo (descritas abaixo):
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable" />
2. Um provedor de contedo que pode oferecer sugestes de pesquisa de acordo
com as URIs e formatos de coluna especificada pelo Sugestes de Pesquisa
seo do docs SearchManager.
<!-- Provides search suggestions for words and their definitions. -->
<provider android:name="DictionaryProvider"
android:authorities="dictionary"
android:syncable="false" />
No searchable.xml, voc especifica algumas coisas sobre como voc deseja
que o sistema de busca apresente a pesquisa para a sua aplicao, incluindo a
autoridade do provedor de contedo que oferece sugestes para o usurio
enquanto digitam. Aqui est um exemplo do searchable.xml de um aplicativo
do Android que fornece sugestes de pesquisa dentro de suas prprias
atividades:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
android:searchSuggestAuthority="dictionary"
android:searchSuggestIntentAction="android.intent.action.VIEW">
</searchable>

ANDROID, uma viso geral Anderson Duarte de Amorim
257
No Android 1.6, que adicionou um novo atributo para os metadados conhecido como:
android:includeInGlobalSearch. Especificando-a como "true" no seu searchable.xml,
voc permite que QSB a pegar sua pesquisa provedor de contedo e d sugesto de
incluso (se o usurio permite que suas sugestes a partir das definies de pesquisa do
sistema).
Voc tambm deve especificar um valor de cadeia para
android:searchSettingsDescription, que descreve aos usurios que tipo de sugestes o
seu aplicativo fornece nas configuraes do sistema para a pesquisa.
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
android:searchSettingsDescription="@string/settings_description"
android:includeInGlobalSearch="true"
android:searchSuggestAuthority="dictionary"
android:searchSuggestIntentAction="android.intent.action.VIEW">
</searchable>
O mais importante e primeira coisa a notar que quando um usurio instala um
aplicativo com um provedor de sugesto que participam no CPR, esta nova aplicao
no ser ativado por padro para o CPR. O usurio pode optar por ativar as fontes de
sugesto especial, as configuraes do sistema para a pesquisa (clicando em "Pesquisar"
> "itens pesquisveis" nas configuraes).
Voc deve pensar em como lidar com isso em sua aplicao. Talvez mostrar um aviso
de que instrui o usurio a visitar as configuraes do sistema e permitir as sugestes do
seu aplicativo.
Quando o usurio habilita o item pesquisado, sugestes do aplicativo tero a chance de
aparecer na QSB. Como sugestes de sua aplicao so escolhidas com mais freqncia,
eles podem se mover para cima na lista.
ANDROID, uma viso geral Anderson Duarte de Amorim
258

Um dos nossos objetivos com o CPR torn-lo mais rpido para que os usurios
acessem as coisas com mais freqncia. Uma maneira que fizemos isso 'shortcutting'
algumas das sugestes de pesquisa previamente escolhido, ento eles sero mostrados
imediatamente quando o usurio comea a digitar, ao invs de esperar para consultar os
fornecedores de contedos. Sugestes de sua aplicao podem ser escolhidas como
atalhos quando o usurio clica neles.
Para sugestes de dinmicas que podem querer alterar o seu contedo (ou se tornar
invlido), no futuro, voc pode fornecer um 'id atalho.
Sistema
Alocao de memria
Escrever eficazes aplicaes mveis nem sempre fcil. Em particular, aplicaes
Android dependem de gerenciamento automtico de memria manipulado pelo coletor
de lixo Dalvik, que por vezes pode causar problemas de desempenho se voc no for
cuidadoso com as alocaes de memria.
Em um caminho de cdigo de desempenho sensveis, tais como o mtodo de layout ou
desenho de uma vista ou o cdigo da lgica de um jogo, qualquer atribuio tem um
preo. Depois de muitas atribuies, o coletor de lixo vai comear e parar o aplicativo
para deix-lo liberar memria. Na maioria das vezes, as coletas de lixo acontecem
rpidas o suficiente para voc no perceber. No entanto, se uma coleo acontece
enquanto voc estiver percorrendo uma lista de itens ou enquanto voc est tentando
ANDROID, uma viso geral Anderson Duarte de Amorim
259
derrotar um inimigo em um jogo, voc pode de repente ver uma queda no desempenho/
capacidade de resposta do aplicativo. No incomum para uma coleta de lixo levar de
100 a 200 ms. Para comparao, uma animao suave precisa desenhar cada quadro em
16 a 33 ms. Se a animao subitamente interrompida por 10 quadros, voc pode estar
certo que os usurios iro notar.
Na maioria das vezes, a coleta de lixo ocorre por causa de toneladas de objetos
pequenos, de curta durao e alguns coletores de lixo, como catadores de lixo de
geraes, que podem otimizar a coleta desses objetos para que o aplicativo no se
interrompa com muita freqncia. O coletor de lixo Android infelizmente no capaz
de realizar tais otimizaes e na criao de objetos de curta durao em caminhos de
cdigo crtico de desempenho , portanto, muito caro para sua aplicao.
Para ajudar a evitar freqentes coletas de lixo, o SDK do Android embarcado com
uma ferramenta muito til chamado allocation tracker. Esta ferramenta parte do
DDMS, que voc j deve ter usado para fins de depurao. Para comear a usar o
tracker de atribuio, primeiro voc deve lanar a verso autnoma do DDMS, que pode
ser encontrado na tools/ do SDK. A verso do DDMS includo no Eclipse plugin no
oferece capacidade de usar o tracker de atribuio ainda.
Depois DDMS estar funcionando, basta selecionar o seu processo de candidatura e, em
seguida, clique na guia Atribuio Tracker. Na nova viso, clique em Iniciar
monitoramento e ento usar o aplicativo para torn-lo executvel para os caminhos de
cdigo que voc deseja analisar. Quando estiver pronto, clique em Obter atribuies.
Uma lista de objetos alocados ser mostrada no primeiro quadro. Ao clicar em uma
linha voc pode ver, na segunda tabela, o rastreamento de pilha que levaram
atribuio. No somente voc saber que tipo de objeto foi alocado, mas tambm em
qual segmento, em que classe, em qual arquivo e em qual linha. A figura abaixo mostra
as atribuies realizadas por prateleiras enquanto estiver rolando um ListView.
ANDROID, uma viso geral Anderson Duarte de Amorim
260

O tracker de atribuio ajudar voc a identificar questes importantes em seu cdigo.
Por exemplo, um erro comum que tenho visto em muitas aplicaes a criao de uma
novo objeto Paint em cada sorteio. Mover a pintura em um campo de instncia uma
soluo simples que ajuda no desempenho de um lote. Eu altamente encorajo-vos a
examinar o cdigo fonte do Android para ver como podemos reduzir dotaes em
caminhos de cdigo crtico de desempenho. Voc tambm vai descobrir o Android,
assim, oferecer APIs para ajudar voc a reutilizar objetos.
Zipaling oferece uma otimizao fcil
O Android SDK inclui uma ferramenta chamada zipalign que otimiza a forma como um
aplicativo empacotado. Rodando Zipalign em seu aplicativo permite que o Android
possa interagir de forma mais eficiente em tempo de execuo e, portanto, tem o
potencial para faz-lo executar o sistema global mais rpido.
No Android, arquivos de dados armazenados em APK de cada aplicativo so acessados
por vrios processos: o instalador l o manifesto para lidar com as permisses
associadas com o pedido; a aplicao inicial l recursos para obter o nome do aplicativo
ANDROID, uma viso geral Anderson Duarte de Amorim
261
e um cone; o sistema servidor l os recursos para uma variedade de razes (por
exemplo, para exibir as notificaes que aplicativo), e por ltimo mas no menos
importante, os arquivos de recurso so, obviamente, utilizado pelo prprio aplicativo.
Os cdigos de manipulao de recursos no Android podem acessar os recursos de forma
eficiente quando esto alinhados em limites de 4 bytes de memria. Mas, para recursos
que no esto alinhados (ou seja, quando zipalign no tenha sido executado em um
APK), ele tem que cair de volta a expressamente e l-los - o que mais lento e consome
memria adicional.
Para um desenvolvedor de aplicativos, este mecanismo de retorno muito conveniente.
Ele oferece uma grande flexibilidade, permitindo o desenvolvimento de vrios mtodos
diferentes, incluindo aqueles que no incluem a agregao de recursos como parte de
seu fluxo normal.
Infelizmente, para os usurios a situao inversa - os recursos de leitura de APKs
desalinhados so lentos e exigem muito da memria. No melhor dos casos, o nico
resultado visvel que tanto a aplicao inicial quanto o lanamento de aplicaes
desalinhadas so mais lentos do que deveria. No pior dos casos, a instalao de vrias
aplicaes com recursos de memria no alinhadas aumentam a presso, causando
assim problemas para o sistema por ter que constantemente iniciar e matar processos. O
usurio acaba com um dispositivo lento, com uma durao de bateria fraca.
Felizmente, muito fcil para o alinhar recursos em sua aplicao:
Usando ADT:
o A ADT, plugin para o Eclipse (a partir da verso 0.9.3), alinhar
automaticamente os pacotes de aplicativos libertados se a assistente de
exportao usado para cri-las.
Usando Ant:
o O script de construo Ant (a partir do Android 1.6) pode alinhar os
pacotes de aplicativos. Metas para verses mais antigas da plataforma
Android no so alinhados pelo script de construo Ant e precisam ser
manualmente alinhados.
ANDROID, uma viso geral Anderson Duarte de Amorim
262
o A partir dos 1,6 Android SDK, Ant alinha pacotes de sinais
automaticamente, quando est construindo o modo de depurao.
o No modo de lanamento, Ant alinha as embalagens se tiver informao
suficiente para assinar os pacotes, uma vez que o alinhamento deve
acontecer aps a assinatura. A fim de poder assinar os pacotes, e,
portanto, para alinh-los, Ant precisa saber a localizao do
armazenamento de chaves e o nome da chave na build.properties. O
nome das propriedades so key.store e key.alias. Se as propriedades
estiverem ausentes, o pacote de lanamento no ser assinado e,
portanto, no vai se alinhar tambm.
Manualmente:
o A fim de alinhar manualmente um pacote, zipalign est no tools/ do
Android SDK 1.6 e posteriores. Voc pode us-lo para alinhar os pacotes
de aplicativos voltados para qualquer verso do Android. Voc deve
execut-lo somente aps a assinatura do arquivo APK, usando o seguinte
comando:
zipalign -v 4 source.apk destination.apk
Verificando o alinhamento:
o O comando a seguir verifica se um pacote est alinhado:
zipalign -c -v 4 application.apk


ANDROID, uma viso geral Anderson Duarte de Amorim
263
Nota
Todo o contedo foi retirado de <http://android.com> e correlatos sendo
disponibilizado atravs da licena Apache 2.0 e traduzido com auxlio de
<http://translate.google.com.br> com posterior reviso.
Fontes
About the Android Open Source Project. Disponvel em:
<http://source.android.com/about/index.html>. Acesso em: 06 abril 2011.
Activities. Disponvel em:
<http://developer.android.com/guide/topics/fundamentals/activities.html>. Acesso em:
22 maro 2011.
Application Resources. Disponvel em:
<http://developer.android.com/guide/topics/resources/index.html>. Acesso em: 05 abril
2011.
Applying Styles and Themes. Disponvel em:
<http://developer.android.com/guide/topics/ui/themes.html>. Acesso em: 04 abril 2011.
Bound Services. Disponvel em:
<http://developer.android.com/guide/topics/fundamentals/bound-services.html>. Acesso
em: 25 maro 2011.
Creating Dialogs. Disponvel em:
<http://developer.android.com/guide/topics/ui/dialogs.html>. Acesso em: 01 abril 2011.
Creating Menus. Disponvel em:
<http://developer.android.com/guide/topics/ui/menus.html>. Acesso em: 30 maro
2011.
Creating Status Bar Notifications. Disponvel em:
<http://developer.android.com/guide/topics/ui/notifiers/notifications.html>. Acesso em:
04 abril 2011.
ANDROID, uma viso geral Anderson Duarte de Amorim
264
Creating Toast Notifications. Disponvel em:
<http://developer.android.com/guide/topics/ui/notifiers/toasts.html>. Acesso em: 04
abril 2011.
Data Backup. Disponvel em:
<http://developer.android.com/guide/topics/data/backup.html>. Acesso em: 06 abril
2011.
Data Storage. Disponvel em:
<http://developer.android.com/guide/topics/data/data-storage.html>. Acesso em: 05
abril 2011.
Declaring Layout. Disponvel em:
<http://developer.android.com/guide/topics/ui/declaring-layout.html>. Acesso em: 29
maro 2011.
Fragments. Disponvel em:
<http://developer.android.com/guide/topics/fundamentals/fragments.html>. Acesso em:
22 maro 2011.
Handling UI Events. Disponvel em:
<http://developer.android.com/guide/topics/ui/ui-events.html>. Acesso em: 04 abril
2011.
How Android Draws Views. Disponvel em:
<http://developer.android.com/guide/topics/ui/how-android-draws.html>. Acesso em:
04 abril 2011.
Loaders. Disponvel em:
<http://developer.android.com/guide/topics/fundamentals/loaders.html>. Acesso em: 23
maro 2011.
Notifying the User. Disponvel em:
<http://developer.android.com/guide/topics/ui/notifiers/index.html>. Acesso em: 04
abril 2011.
Processes and Threads. Disponvel em:
ANDROID, uma viso geral Anderson Duarte de Amorim
265
<http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html>.
Acesso em: 25 maro 2011.

ANDROID, uma viso geral Anderson Duarte de Amorim
266
Services. Disponvel em:
<http://developer.android.com/guide/topics/fundamentals/services.html>. Acesso em:
25 maro 2011.
Tasks and Back Stack. Disponvel em:
<http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html>.
Acesso em: 24 maro 2011.
User Interface. Disponvel em:
<http://developer.android.com/guide/topics/ui/index.html>. Acesso em: 29 maro 2011.
Using the Action Bar. Disponvel em:
<http://developer.android.com/guide/topics/ui/actionbar.html>. Acesso em: 30 maro
2011.
Fontes das imagens
Androids. Disponvel em:
<http://www.android.com/media/wallpaper/gif/androids.gif>. Acesso em: 06 abril 2011.
Untitled. Disponvel em:
<http://t3.gstatic.com/images?q=tbn:ANd9GcSknkUiTjwIBqS6dGp8k5IR2ihXI1ipyrols
9PHvLL2nq9GLVd0lg&t=1>. Acesso em: 04 abril 2011.
Fontes dos artigos
Accessibility Service. Disponvel em:
<http://developer.android.com/resources/samples/AccessibilityService/index.html>.
Acesso em: 18 maro 2011.
Drawable Mutations. Disponvel em:
<http://developer.android.com/resources/articles/drawable-mutations.html>. Acesso em:
18 maro 2011.
Gestures. Disponvel em:
<http://developer.android.com/resources/articles/gestures.html>. Acesso em: 18 maro
2011.
ANDROID, uma viso geral Anderson Duarte de Amorim
267
Layout Tricks: Creating Efficient Layouts. Disponvel em:
<http://developer.android.com/resources/articles/layout-tricks-efficiency.html>. Acesso
em: 21 maro 2011.
Layout Tricks: Merging Layouts. Disponvel em:
<http://developer.android.com/resources/articles/layout-tricks-merge.html>. Acesso em:
21 maro 2011.
Layout Tricks: Using ViewStubs. Disponvel em:
<http://developer.android.com/resources/articles/layout-tricks-stubs.html>. Acesso em:
21 maro 2011.
Live Folders. Disponvel em:
<http http://developer.android.com/resources/articles/live-folders.html>. Acesso em: 21
maro 2011.
Live Wallpapers. Disponvel em:
<http://developer.android.com/resources/articles/live-wallpapers.html>. Acesso em: 21
maro 2011.
ListView Backgrounds: An Optimization. Disponvel em:
<http://developer.android.com/resources/articles/listview-backgrounds.html>. Acesso
em: 21 maro 2011.
Touch Mode. Disponvel em:
<http://developer.android.com/resources/articles/touch-mode.html>. Acesso em: 21
maro 2011.
Using Text-to-Speech. Disponvel em:
<http://developer.android.com/resources/articles/tts.html>. Acesso em: 18 maro 2011.
Zipalign: an Easy Optimization. Disponvel em:
<http://developer.android.com/resources/articles/zipalign.html>. Acesso em: 21 maro
2011.

Você também pode gostar