ANDROID Uma Visao Geral

  • Published on
    29-Dec-2015

  • View
    14

  • Download
    0

Transcript

  • A

    nd

    erso

    n D

    uar

    te d

    e A

    mo

    rim

    20

    11

    AN

    DR

    OID

    , um

    a v

    is

    o g

    era

    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

    como um filho do . Por exemplo:

    ...

    ...

    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 tambm pode especificar filtros diferentes, usando o , 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:

    O elemento especifica que este o "principal ponto de entrada" para o

    aplicativo. O elemento 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 que inclui um elemento

    e, opcionalmente, um elemento e/ou um . 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 , 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

    O atributo android:name na 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 .

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

    // 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 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 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 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 e com

    bandeiras de inteno que voc passa para startActivity().

    Neste sentido, os principais atributos de 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 .

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

    O atributo taskAffinity tem um valor de seqncia, que deve ser exclusivo do nome do

    pacote padro declarada no elemento , 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:

    ...

    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 , 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 como um filho do elemento

    . Por exemplo:

    ...

    ...

    Existem outros atributos que voc pode incluir no 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 devem usar 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 se ligar 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 - ,

  • 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 {

    /** 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 cria um na sua interface do usurio, e um elemento

    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:

  • ANDROID, uma viso geral Anderson Duarte de Amorim 112

    android:layout_height="fill_parent"

    android:orientation="vertical" >

    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 Listener, cada um com um mtodo

    de retorno de chamada On (). 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 :

  • 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:

    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

    Define um Menu, que um recipiente para itens de menu. Um elemento

    deve ser o n raiz para o arquivo e pode conter um ou mais e

    elementos .

    Cria um MenuItem, o que representa um nico item em um menu. Este elemento

    pode conter um elemento aninhado, a fim de criar um submenu.

    Um opcional, recipiente invisvel para elementos . 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:

    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 , 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 como o filho de um . Por exemplo:

    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 dentro de um elemento

    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:

    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 , ou para um grupo inteiro com o

    atributo android:checkableBehavior no elemento . Por exemplo, todos os itens

    deste grupo de menu so verificados com um boto de rdio:

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

    ...

    ...

    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 para "11" ou superior. Por exemplo:

  • ANDROID, uma viso geral Anderson Duarte de Amorim 140

    ...

    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:

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

    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:

    O valor para android:actionViewClass deve ser um nome de classe qualificado

    para o View que voc deseja usar. Por exemplo:

    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:

    Mercury

    Venus

    Earth

    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:

    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:

    @style/customActionBarTabTextStyle

    @style/customActionBarTabStyle

    @style/customActionBarTabBarStyle

    #2966c2

    20sp

    sans

    @drawable/actionbar_tab_bg

    20dp

    20dp

    @drawable/actionbar_tab_bar

    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:

    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:

    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

    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):

  • ANDROID, uma viso geral Anderson Duarte de Amorim 179

    android:layout_width="wrap_content"

    android:layout_height="fill_parent"

    android:textColor="#FFF"

    />

    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:

  • 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:

    E transformar nisso:

    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 .

    Para cada estilo que voc quer criar, adicione um elemento para o arquivo com

    um nome que identifica o estilo (este atributo obrigatrio). Em seguida, adicione um

    elemento 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 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:

    fill_parent

    wrap_content

    #00FF00

    monospace

    Cada filho do elemento convertido em um objeto de recurso do aplicativo

    em tempo de compilao, que pode ser referenciado pelo valor do atributo name do

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

    #00FF00

    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:

    #FF0000

    Observe que no h atributo parent na tag , 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:

    30sp

    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 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 , assim:

    Voc pode em vez disso criar um estilo para o elemento EditText que inclua esta

    propriedade:

    number

    ...

    Portanto, o seu XML para o esquema pode agora aplicar este estilo:

    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

    com o android: namespace. Por exemplo: .

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

    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 para incluir o atributo android:theme

    com o nome do estilo. Por exemplo:

    Se voc quer um tema aplicado a apenas uma atividade em seu aplicativo, ento,

    adicione o atributo android:theme ao tag 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:

    Ou se voc quiser que o fundo seja transparente, usar o tema translcido:

    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:

    #b0b0ff

    @color/custom_theme_color

    @color/custom_theme_color

    (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

    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 ):

    ...

    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:

    ...

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

    O 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//cache/

    O 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 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 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:

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

    ...

    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:

  • ANDROID, uma viso geral Anderson Duarte de Amorim 231

    android:layout_weight="1"

    android:gravity="center_vertical"

    android:text="My Application" />

    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:

  • 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" />

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

    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 .

    Truques de layout: mesclando layouts

    A tag 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

    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 vem a calhar. Quando o LayoutInflater encontra essa marca, ele

    ignora-o e adiciona o dos nodos ao pai. Confuso? Vamos

    reescrever o nosso layout XML anterior, substituindo o FrameLayout com :

  • ANDROID, uma viso geral Anderson Duarte de Amorim 240

    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 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 pode ser til em outras

    situaes, no entanto. Por exemplo, ele funciona perfeitamente quando combinado com

    o . Voc tambm pode usar 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.

  • 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 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:

    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 extremamente til e pode fazer maravilhas em seu cdigo. No entanto,

    ele sofre de um par de limitaes:

    s pode ser usado como a tag raiz de um esquema XML

    Ao inflar um layout comeando com uma 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:

    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 LIVE_FOLDER_PROJECTION_MAP;

    static {

    LIVE_FOLDER_PROJECTION_MAP = new HashMap();

    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:

    , que indica Android Market e

    plataforma que seu aplicativo requer Android 2.1 ou superior.

    , 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 , a inteno do filtro, e uma referncia a um searchable.xml

    arquivo (descritas abaixo):

    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.

    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:

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

    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 e correlatos sendo

    disponibilizado atravs da licena Apache 2.0 e traduzido com auxlio de

    com posterior reviso.

    Fontes

    About the Android Open Source Project. Disponvel em:

    . Acesso em: 06 abril 2011.

    Activities. Disponvel em:

    . Acesso em:

    22 maro 2011.

    Application Resources. Disponvel em:

    . Acesso em: 05 abril

    2011.

    Applying Styles and Themes. Disponvel em:

    . Acesso em: 04 abril 2011.

    Bound Services. Disponvel em:

    . Acesso

    em: 25 maro 2011.

    Creating Dialogs. Disponvel em:

    . Acesso em: 01 abril 2011.

    Creating Menus. Disponvel em:

    . Acesso em: 30 maro

    2011.

    Creating Status Bar Notifications. Disponvel em:

    . Acesso em:

    04 abril 2011.

  • ANDROID, uma viso geral Anderson Duarte de Amorim 264

    Creating Toast Notifications. Disponvel em:

    . Acesso em: 04

    abril 2011.

    Data Backup. Disponvel em:

    . Acesso em: 06 abril

    2011.

    Data Storage. Disponvel em:

    . Acesso em: 05

    abril 2011.

    Declaring Layout. Disponvel em:

    . Acesso em: 29

    maro 2011.

    Fragments. Disponvel em:

    . Acesso em:

    22 maro 2011.

    Handling UI Events. Disponvel em:

    . Acesso em: 04 abril

    2011.

    How Android Draws Views. Disponvel em:

    . Acesso em:

    04 abril 2011.

    Loaders. Disponvel em:

    . Acesso em: 23

    maro 2011.

    Notifying the User. Disponvel em:

    . Acesso em: 04

    abril 2011.

    Processes and Threads. Disponvel em:

  • ANDROID, uma viso geral Anderson Duarte de Amorim 265

    .

    Acesso em: 25 maro 2011.

  • ANDROID, uma viso geral Anderson Duarte de Amorim 266

    Services. Disponvel em:

    . Acesso em:

    25 maro 2011.

    Tasks and Back Stack. Disponvel em:

    .

    Acesso em: 24 maro 2011.

    User Interface. Disponvel em:

    . Acesso em: 29 maro 2011.

    Using the Action Bar. Disponvel em:

    . Acesso em: 30 maro

    2011.

    Fontes das imagens

    Androids. Disponvel em:

    . Acesso em: 06 abril 2011.

    Untitled. Disponvel em:

    . Acesso em: 04 abril 2011.

    Fontes dos artigos

    Accessibility Service. Disponvel em:

    .

    Acesso em: 18 maro 2011.

    Drawable Mutations. Disponvel em:

    . Acesso em:

    18 maro 2011.

    Gestures. Disponvel em:

    . Acesso em: 18 maro

    2011.

  • ANDROID, uma viso geral Anderson Duarte de Amorim 267

    Layout Tricks: Creating Efficient Layouts. Disponvel em:

    . Acesso

    em: 21 maro 2011.

    Layout Tricks: Merging Layouts. Disponvel em:

    . Acesso em:

    21 maro 2011.

    Layout Tricks: Using ViewStubs. Disponvel em:

    . Acesso em:

    21 maro 2011.

    Live Folders. Disponvel em:

    . Acesso em: 21

    maro 2011.

    Live Wallpapers. Disponvel em:

    . Acesso em: 21

    maro 2011.

    ListView Backgrounds: An Optimization. Disponvel em:

    . Acesso

    em: 21 maro 2011.

    Touch Mode. Disponvel em:

    . Acesso em: 21

    maro 2011.

    Using Text-to-Speech. Disponvel em:

    . Acesso em: 18 maro 2011.

    Zipalign: an Easy Optimization. Disponvel em:

    . Acesso em: 21 maro

    2011.