diff options
Diffstat (limited to 'docs/html-intl/intl/pt-br/guide/components')
11 files changed, 6216 insertions, 0 deletions
diff --git a/docs/html-intl/intl/pt-br/guide/components/activities.jd b/docs/html-intl/intl/pt-br/guide/components/activities.jd new file mode 100644 index 000000000000..71986abe649b --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/activities.jd @@ -0,0 +1,756 @@ +page.title=Atividades +page.tags=atividade,intenção +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> +<h2>Neste documento</h2> +<ol> + <li><a href="#Creating">Criação de uma atividade</a> + <ol> + <li><a href="#UI">Implementação de uma interface do usuário</a></li> + <li><a href="#Declaring">Declaração de uma atividade no manifesto</a></li> + </ol> + </li> + <li><a href="#StartingAnActivity">Início de uma atividade</a> + <ol> + <li><a href="#StartingAnActivityForResult">Início de uma atividade de um resultado</a></li> + </ol> + </li> + <li><a href="#ShuttingDown">Encerramento de uma atividade</a></li> + <li><a href="#Lifecycle">Gerenciamento do ciclo de vida da atividade</a> + <ol> + <li><a href="#ImplementingLifecycleCallbacks">Implementação de retornos de chamada do ciclo de vida</a></li> + <li><a href="#SavingActivityState">Gravação do estado da atividade</a></li> + <li><a href="#ConfigurationChanges">Manipulação de alterações de configuração</a></li> + <li><a href="#CoordinatingActivities">Coordenação de atividades</a></li> + </ol> + </li> +</ol> + +<h2>Classes principais</h2> +<ol> + <li>{@link android.app.Activity}</li> +</ol> + +<h2>Veja também</h2> +<ol> + <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tarefas e pilha +de retorno</a></li> +</ol> + +</div> +</div> + + + +<p>{@link android.app.Activity} é um componente de aplicativo que fornece uma tela com a qual +os usuários podem interagir para fazer algo, como discar um número no telefone, tirar uma foto, enviar um e-mail +ou ver um mapa. Cada atividade recebe uma janela que exibe a interface do usuário. Geralmente, a janela +preenche a tela, mas pode ser menor que a tela e flutuar +sobre outras janelas.</p> + +<p> Aplicativos geralmente possuem várias atividades pouco vinculadas +entre si. Normalmente, uma atividade em um aplicativo é especificada como "principal", +que é a apresentada ao usuário ao iniciar o aplicativo pela primeira vez. Cada +atividade pode, então, iniciar outra atividade para executar diferentes ações. Ao iniciar uma nova +atividade, a atividade anterior é interrompida, mas o sistema conserva a atividade +em uma pilha (a "pilha de retorno"). Quando uma atividade inicia, ela é enviada para a pilha de retorno +e obtém o foco do usuário. A pilha de retorno segue o mecanismo básico de pilha UEPS (o último que entra é o primeiro que sai). +Assim, quando o usuário terminar a atividade atual e apertar o botão <em>Voltar</em>, +ela sairá da pilha (é destruída) e a atividade anterior será retomada (a pilha de retorno +é discutida em mais detalhes no documento <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tarefas +e Pilha de Retorno</a>).</p> + +<p>Quando uma atividade é interrompida devido ao início de uma nova atividade, ela é notificada acerca dessa alteração de estado +por meio de métodos de retorno de chamada do ciclo de vida da atividade. +Há diversos métodos de retorno de chamada que uma atividade pode receber devido a uma alteração +em seu estado — quando o sistema a está criando, interrompendo, retomando ou destruindo — e cada +retorno de chamada oferece uma oportunidade de executar trabalhos específicos +adequados a essa alteração de estado. Por exemplo: quando interrompida, a atividade deve liberar +todos os objetos grandes, como conexões com a rede ou com um banco de dados. Quando a atividade for retomada, será possível +readquirir os recursos necessários e retomar as ações interrompidas. Essas transições de estado +são parte do ciclo de vida da atividade.</p> + +<p>O restante deste documento discute o básico sobre a compilação e o uso de uma atividade, +incluindo uma discussão completa sobre o funcionamento do ciclo de vida da atividade para gerenciar adequadamente +a transição entre os diversos estados da atividade.</p> + + + +<h2 id="Creating">Criação de uma atividade</h2> + +<p>Para criar uma atividade, é preciso criar uma subclasse de {@link android.app.Activity} +(ou uma respectiva subclasse existente). Na subclasse, é preciso implementar um método de retorno de chamada +que o sistema chama quando ocorre a transição entre os diversos estados de seu ciclo de vida, +como na criação, interrupção, retomada ou destruição da atividade. Os dois métodos mais importantes +de retorno de chamada são:</p> + +<dl> + <dt>{@link android.app.Activity#onCreate onCreate()}</dt> + <dd>É preciso implementar esse método. O sistema o chama ao criar +a atividade. Na implementação, é preciso inicializar os componentes essenciais +da atividade. + E, fundamentalmente, é quando se deve chamar {@link android.app.Activity#setContentView +setContentView()} para definir o layout da interface do usuário da atividade.</dd> + <dt>{@link android.app.Activity#onPause onPause()}</dt> + <dd>O sistema chama esse método como o primeiro indício de que o usuário está saindo +da atividade (embora não seja sempre uma indicação de que a atividade será destruída). É quando geralmente +se deve confirmar qualquer alteração que deva persistir além da sessão do usuário atual (porque +o usuário pode não retornar).</dd> +</dl> + +<p>Há outros métodos de retorno de chamada do ciclo de vida que se pode usar para oferecer +uma experiência fluida ao usuário entre atividades e manipular interrupções inesperadas que venham a parar +ou até a destruir a atividade. Todos os métodos de retorno de chamada do ciclo de vida serão discutidos mais adiante +na seção sobre <a href="#Lifecycle">Gerenciamento do ciclo de vida da atividade</a>.</p> + + + +<h3 id="UI">Implementação de uma interface do usuário</h3> + +<p> A interface do usuário de uma atividade é fornecida por uma hierarquia de objetos — de vistas derivados +da classe {@link android.view.View}. Cada vista controla um espaço retangular específico +dentro da janela da atividade e pode responder à interação com o usuário. Por exemplo: uma vista pode ser +um botão que inicia uma ação quando o usuário toca nele.</p> + +<p>O Android oferece algumas vistas prontas que podem ser usadas para projetar e organizar +o layout. "Widgets" são vistas que fornecem elementos visuais (e interativos) à tela, +como um botão, um campo de texto, uma caixa de seleção ou apenas uma imagem. "Layouts" são vistas derivadas de {@link +android.view.ViewGroup} que oferecem um modelo de layout exclusivo para suas vistas filhas, +como um layout linear, um layout em grade ou um layout relativo. Também é possível definir como subclasse as classes +{@link android.view.View} e {@link android.view.ViewGroup} (ou subclasses existentes) para criar widgets e layouts próprios +e aplicá-los no layout da atividade.</p> + +<p>A forma mais comum de definir um layout usando vistas é com um arquivo de layout XML salvo +nos recursos do aplicativo. Assim, é possível manter o projeto da interface do usuário separado +do código fonte que define o comportamento da atividade. É possível definir o layout como a IU da atividade +com {@link android.app.Activity#setContentView(int) setContentView()}, passando +o ID de recurso do layout. No entanto, também é possível criar novas {@link android.view.View}s +no código da atividade e compilar uma hierarquia de vistas inserindo novas {@link +android.view.View}s em um {@link android.view.ViewGroup} e, em seguida, usar esse layout passando a raiz +{@link android.view.ViewGroup} para {@link android.app.Activity#setContentView(View) +setContentView()}.</p> + +<p>Para obter mais informações sobre a criação de uma interface do usuário, consulte a documentação <a href="{@docRoot}guide/topics/ui/index.html">Interface do Usuário</a>.</p> + + + +<h3 id="Declaring">Declaração de uma atividade no manifesto</h3> + +<p>É preciso declarar a atividade no arquivo de manifesto para torná-la +acessível para o sistema. Para declarar a atividade, abra o arquivo de manifesto e adicione um elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> +como filho do elemento +<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>. Por exemplo:</p> + +<pre> +<manifest ... > + <application ... > + <activity android:name=".ExampleActivity" /> + ... + </application ... > + ... +</manifest > +</pre> + +<p>Existem outros atributos que podem ser incluídos nesse elemento para definir propriedades +como o rótulo da atividade, um ícone para a atividade ou um tema para estilizar a IU da atividade. + O atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a> + é o único atributo obrigatório — ele especifica o nome de classe da atividade. Depois +de publicar o aplicativo, não se deve alterar-lhe o nome porque, se isso acontecer, podem ocorrer danos +em algumas funcionalidades, como os atalhos do aplicativo (leia a publicação do blogue <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Coisas +que não podem mudar</a>).</p> + +<p>Consulte a referência do elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> +para obter mais informações sobre como declarar a atividade no manifesto.</p> + + +<h4>Uso de filtros de intenções</h4> + +<p>Um elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a> também pode especificar vários filtros de intenções — usando o elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> — para declarar o modo com que os componentes de aplicativo +podem ativá-lo.</p> + +<p>Ao criar um novo aplicativo com as ferramentas do Android SDK, o esboço da atividade +criado contém automaticamente um filtro de intenção que declara que a atividade responde +à ação "main" (principal) e deve ser colocada na categoria "launcher” (inicializador). O filtro de intenção +tem a seguinte aparência:</p> + +<pre> +<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +</pre> + +<p>O elemento <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> especifica que este é o “principal” ponto de entrada do aplicativo. O elemento <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> especifica que essa atividade deve ser listada no inicializador do aplicativo +do sistema (para permitir que os usuários iniciem essa atividade).</p> + +<p>Se pretende-se que o aplicativo seja autônomo e que não permita que outros aplicativos ativem +suas atividades, não será necessário nenhum outro filtro de intenção. Só uma atividade deve ter +a ação "main" e a categoria "launcher", como no exemplo anterior. As atividades +que não devem estar disponíveis a outros aplicativos não devem ter filtros de intenção, já que é possível +iniciá-las por meio de intenções explícitas (conforme discutido na seção a seguir).</p> + +<p>No entanto, se a atividade deve responder a intenções implícitas derivadas de outros aplicativos +(e do aplicativo em questão), é preciso definir filtros de intenções adicionais +para a atividade. Para cada tipo de intenção que deve responder, é preciso incluir um <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> que contenha um elemento +<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a> e, opcionalmente, um elemento <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a> e/ou um elemento <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a>. Esses elementos especificam o tipo de intenção a que a atividade pode +responder.</p> + +<p>Para obter mais informações sobre a forma com que as atividades podem responder a intenções, consulte o documento +<a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de intenções</a>.</p> + + + +<h2 id="StartingAnActivity">Início de uma atividade</h2> + +<p>Para iniciar outra atividade, é possível chamar {@link android.app.Activity#startActivity +startActivity()} passando uma {@link android.content.Intent} que descreva a atividade +que se deseja iniciar. A intenção especifica a atividade exata que deve ser iniciada ou descreve o tipo +de ação que ela deve executar (e o sistema seleciona a atividade adequada, +que +pode ser até de um outro aplicativo). Uma intenção também pode portar pequenas quantidades de dados +a serem usados pela atividade iniciada.</p> + +<p>Ao trabalhar no aplicativo, frequentemente será necessário iniciar uma atividade conhecida. + Para isso, pode-se criar uma intenção que defina explicitamente a atividade que deve ser iniciada +por meio de um nome de classe. Por exemplo, a seguir é demonstrado como uma atividade inicia outra atividade de nome {@code +SignInActivity}:</p> + +<pre> +Intent intent = new Intent(this, SignInActivity.class); +startActivity(intent); +</pre> + +<p>No entanto, o aplicativo também pode ter que executar algumas ações, como enviar um e-mail, +mensagem de texto ou atualização de status usando os dados da atividade em questão. Nesse caso, o aplicativo +pode não ter suas próprias atividades para executar tais ações; para isso, pode-se aproveitar as atividades +fornecidas por outros aplicativos do dispositivo que podem executar essas ações. Esses são os casos +em que as intenções são muito importantes — é possível criar uma intenção que descreva +uma ação a executar para que o sistema +inicie a atividade apropriada de outro aplicativo. Se houver +mais de uma atividade que possa manipular a intenção, o usuário poderá escolher qual usará. Por exemplo: + se quiser que o usuário envie uma mensagem de e-mail, é possível criar +a seguinte intenção:</p> + +<pre> +Intent intent = new Intent(Intent.ACTION_SEND); +intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); +startActivity(intent); +</pre> + +<p>O {@link android.content.Intent#EXTRA_EMAIL} adicionado à intenção é uma matriz de sequência +de endereços de e-mail para os quais o e-mail poderá ser enviado. Quando um aplicativo de e-mail responde à essa intenção, +ele lê a matriz de sequência fornecida no extra e a coloca no campo "para" +do formulário de composição do e-mail. Nessa situação, a atividade do aplicativo de e-mail inicia e, quando o usuário termina o trabalho, +sua atividade é retomada.</p> + + + + +<h3 id="StartingAnActivityForResult">Início de uma atividade para um resultado</h3> + +<p>Às vezes, é necessário receber um resultado de alguma atividade iniciada. Nesse caso, + inicie a atividade chamando {@link android.app.Activity#startActivityForResult +startActivityForResult()} (em vez de {@link android.app.Activity#startActivity + startActivity()}). Para receber o resultado de uma atividade +subsequente, implemente o método de retorno de chamada +{@link android.app.Activity#onActivityResult onActivityResult()}. Quando a atividade subsequente estiver concluída, ela retornará um resultado em uma {@link +android.content.Intent} para o método +{@link android.app.Activity#onActivityResult onActivityResult()}.</p> + +<p>Por exemplo, talvez você queira que o usuário escolha um dos contatos dele, deste modo, a atividade poderá +fazer algo com as informações naquele contato. A seguir expõe-se como criar uma intenção desse tipo +e manipular o resultado:</p> + +<pre> +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); + // Do something with the selected contact's name... + } + } +} +</pre> + +<p>Esse exemplo mostra a lógica básica que deve ser usada no método {@link +android.app.Activity#onActivityResult onActivityResult()} para manipular +o resultado de uma atividade. A primeira condição verifica se a solicitação foi bem-sucedida — se for, +o {@code resultCode} será {@link android.app.Activity#RESULT_OK} — e se a solicitação +a que esse resultado responderá for desconhecida —, nesse caso, o {@code requestCode} corresponderá +ao segundo parâmetro com {@link android.app.Activity#startActivityForResult +startActivityForResult()}. A partir daí, o código manipula o resultado da atividade com uma consulta +dos dados retornados em uma {@link android.content.Intent} (o parâmetro {@code data}).</p> + +<p>Nesse momento, um {@link +android.content.ContentResolver} executa uma consulta em um provedor de conteúdo, que retorna +um {@link android.database.Cursor} que permite a leitura dos dados consultados. Para obter mais informações, +consulte o documento <a href="{@docRoot}guide/topics/providers/content-providers.html">Provedores de conteúdo</a>.</p> + +<p>Para obter mais informações sobre intenções, consulte o documento +<a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de intenções</a>.</p> + + +<h2 id="ShuttingDown">Encerramento de uma atividade</h2> + +<p>Para encerrar uma atividade, chame o método {@link android.app.Activity#finish +finish()}. Também é possível encerrar uma atividade separada iniciada anteriormente chamando +{@link android.app.Activity#finishActivity finishActivity()}.</p> + +<p class="note"><strong>Observação:</strong> na maioria dos casos, não se deve finalizar explicitamente +uma atividade usando esses métodos. Conforme discutido na seção anterior sobre o ciclo de vida da atividade, +o sistema Android gerencia a vida de uma atividade, portanto não é necessário finalizar +as atividades. Chamar esses métodos poderia afetar negativamente a experiência +do usuário esperada e isso só deve ser usado quando realmente não se desejar que o usuário +retorne a essa instância da atividade.</p> + + +<h2 id="Lifecycle">Gerenciamento do ciclo de vida da atividade</h2> + +<p>O gerenciamento do ciclo de vida das atividades por meio da implementação +de métodos de retorno de chamada +é essencial para desenvolver um aplicativo flexível. O ciclo de vida de uma atividade é diretamente afetado +por sua associação a outras atividades, sua tarefa e sua pilha de retorno.</p> + +<p>Uma atividade pode existir essencialmente em três estados:</p> + +<dl> + <dt><i>Retomada</i></dt> + <dd>A atividade está em primeiro plano na tela e tem o foco do usuário (em geral, +chama-se esse estado de "em execução”).</dd> + + <dt><i>Pausada</i></dt> + <dd>A atividade ainda está visível, mas outra atividade está em primeiro plano e tem o foco. Ou seja, +outra atividade está visível por cima desta e está parcialmente transparente +ou não cobre inteiramente a tela. Uma atividade pausada está totalmente ativa (o objeto +{@link android.app.Activity} está retido na memória, mantém todas as informações de estado e do membro e permanece anexado +ao gerenciador de janela), mas pode ser eliminada pelo sistema em situações de memória extremamente baixa.</dd> + + <dt><i>Interrompida</i></dt> + <dd>A atividade está totalmente suplantada por outra (a atividade passa para +"segundo plano"). Uma atividade interrompida ainda está ativa (o objeto +{@link android.app.Activity} está retido na memória, mantém todas as informações de estado e do membro, mas <em>não</em> está +anexado ao gerenciador de janelas). No entanto, ela não fica mais visível para o usuário +e pode ser eliminada pelo sistema se a memória for necessária em outro processo.</dd> +</dl> + +<p>Se uma atividade estiver pausada ou interrompida, o sistema poderá descartá-la da memória solicitando a +finalização do processo (chamando seu método {@link android.app.Activity#finish finish()}) ou simplesmente +eliminando-o. Quando a atividade for reaberta (depois de finalizada ou eliminada), ele deverá ser +totalmente recriada.</p> + + + +<h3 id="ImplementingLifecycleCallbacks">Implementação de retornos de chamada do ciclo de vida</h3> + +<p>Quando uma atividade transita entre os diferentes estados descritos acima, ela é notificada +por meio de vários métodos de retorno de chamada. Todos os métodos de retorno de chamada são ganchos +que podem ser substituídos para executar um trabalho adequado quando o estado da atividade muda. O esqueleto de atividade +a seguir contém cada um dos métodos do ciclo de vida fundamentais:</p> + + +<pre> +public class ExampleActivity extends Activity { + @Override + public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // The activity is being created. + } + @Override + protected void {@link android.app.Activity#onStart onStart()} { + super.onStart(); + // The activity is about to become visible. + } + @Override + protected void {@link android.app.Activity#onResume onResume()} { + super.onResume(); + // The activity has become visible (it is now "resumed"). + } + @Override + protected void {@link android.app.Activity#onPause onPause()} { + super.onPause(); + // Another activity is taking focus (this activity is about to be "paused"). + } + @Override + protected void {@link android.app.Activity#onStop onStop()} { + super.onStop(); + // The activity is no longer visible (it is now "stopped") + } + @Override + protected void {@link android.app.Activity#onDestroy onDestroy()} { + super.onDestroy(); + // The activity is about to be destroyed. + } +} +</pre> + +<p class="note"><strong>Observação:</strong> a implementação desses métodos do ciclo de vida +deve sempre chamar a implementação da superclasse antes de realizar qualquer trabalho, conforme ilustrado no exemplo acima.</p> + +<p>Juntos, esses métodos definem todo o ciclo de vida da atividade. Ao implementá-los, +é possível monitorar três loops aninhados no ciclo de vida da atividade: </p> + +<ul> +<li><b>Todo o tempo de vida</b> de uma atividade acontece entre a chamada de {@link +android.app.Activity#onCreate onCreate()} e a chamada de {@link +android.app.Activity#onDestroy}. A atividade deve executar configuração +de estado "global" (como definindo layout) em {@link android.app.Activity#onCreate onCreate()} +e liberar todos os recursos restantes em {@link android.app.Activity#onDestroy}. Por exemplo: se a sua atividade +tiver um encadeamento em execução em segundo plano para baixar dados da rede, ela pode +criá-lo em {@link android.app.Activity#onCreate onCreate()} e, em seguida, interrompê-lo em {@link +android.app.Activity#onDestroy}.</li> + +<li><p>O <b>tempo de vida visível</b> de uma atividade acontece entre a chamada de {@link +android.app.Activity#onStart onStart()} e a chamada de {@link +android.app.Activity#onStop onStop()}. Durante esse tempo, o usuário pode ver a atividade +na tela e interagir com ela. Por exemplo: {@link android.app.Activity#onStop onStop()} é chamado +quando uma nova atividade inicia e esta não fica mais visível. Entre esses dois métodos, é possível +manter os recursos necessários para exibir a atividade ao usuário. Por exemplo: você pode registrar +um {@link android.content.BroadcastReceiver} em {@link +android.app.Activity#onStart onStart()} para monitorar as alterações que afetem a IU e cancelar o registro + em {@link android.app.Activity#onStop onStop()} quando o usuário não puder mais ver +o que você está exibindo. O sistema pode chamar {@link android.app.Activity#onStart onStart()} e {@link +android.app.Activity#onStop onStop()} várias vezes durante todo o tempo de vida de uma atividade +enquanto ela alterna entre visível e oculta ao usuário.</p></li> + +<li><p>O <b>tempo de vida em primeiro plano</b> de uma atividade ocorre entre a chamada de {@link +android.app.Activity#onResume onResume()} e a chamada de {@link android.app.Activity#onPause +onPause()}. Durante esse tempo, a atividade está na frente de todas as outras atividades na tela +e tem o foco de interação do usuário. Frequentemente, uma atividade pode transitar entre o primeiro e +o segundo plano — por exemplo, {@link android.app.Activity#onPause onPause()} é chamado quando o dispositivo está em suspensão +ou quando uma caixa de diálogo é exibida. Como esse estado pode transitar frequentemente, o código nesses dois métodos deve +ser bem leve para evitar transições lentas que façam o usuário esperar.</p></li> +</ul> + +<p>A figura 1 ilustra esses loops e os caminhos que uma atividade pode tomar entre os estados. +Os retângulos representam os métodos de retorno de chamada que podem ser implementados para executar operações +quando a atividade transita entre estados. <p> + +<img src="{@docRoot}images/activity_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Figura 1.</strong> Ciclo de vida da atividade.</p> + +<p>Os mesmos métodos de retorno de chamada do ciclo de vida são listados na tabela 1, que descreve cada um deles +em mais detalhes e localiza cada um dentro +do ciclo de vida geral da atividade, inclusive se o sistema puder eliminar a atividade depois +da conclusão do método de retorno de chamada.</p> + +<p class="table-caption"><strong>Tabela 1.</strong> Resumo dos métodos de retorno de chamada +do ciclo de vida da atividade.</p> + +<table border="2" width="85%" frame="hsides" rules="rows"> +<colgroup align="left" span="3"></colgroup> +<colgroup align="left"></colgroup> +<colgroup align="center"></colgroup> +<colgroup align="center"></colgroup> + +<thead> +<tr><th colspan="3">Método</th> <th>Descrição</th> <th>Eliminável depois de?</th> <th>Próximo</th></tr> +</thead> + +<tbody> +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td> + <td>Chamado quando a atividade é criada pela primeira vez. + É quando deve-se fazer toda a configuração estática normal — +criar vistas, vincular dados a listas etc. Esse método recebe +um objeto Bundle (pacote) contendo o estado anterior da atividade, se esse +estado for capturado (consulte <a href="#actstate">Gravação do estado da atividade</a> +mais adiante). + <p>Sempre seguido de {@code onStart()}.</p></td> + <td align="center">Não</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td rowspan="5" style="border-left: none; border-right: none;"> </td> + <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart +onRestart()}</code></td> + <td>Chamado depois que atividade tiver sido interrompida, logo antes de ser +reiniciada. + <p>Sempre seguido de {@code onStart()}.</p></td> + <td align="center">Não</td> + <td align="center">{@code onStart()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td> + <td>Chamado logo antes de a atividade se tornar visível ao usuário. + <p>Seguido de {@code onResume()} se a atividade +for para segundo plano ou {@code onStop()} se ficar oculta.</p></td> + <td align="center">Não</td> + <td align="center">{@code onResume()} <br/>ou<br/> {@code onStop()}</td> +</tr> + +<tr> + <td rowspan="2" style="border-left: none;"> </td> + <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td> + <td>Chamado logo antes de a atividade iniciar +a interação com o usuário. Nesse ponto, a atividade estará +no topo da pilha de atividades com a entrada do usuário direcionada a ela. + <p>Sempre seguido de {@code onPause()}.</p></td> + <td align="center">Não</td> + <td align="center">{@code onPause()}</td> +</tr> + +<tr> + <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td> + <td>Chamado quando o sistema está prestes a retomar +outra atividade. Esse método normalmente é usado para confirmar alterações +não salvas a dados persistentes, animações interrompidas e outras coisas que talvez +estejam consumindo CPU e assim por diante. Ele sempre deve fazer tudo bem rapidamente porque +a próxima atividade não será retomada até ela retornar. + <p>Seguido de {@code onResume()} se a atividade +retornar para a frente ou de {@code onStop()} se ficar +invisível ao usuário.</td> + <td align="center"><strong style="color:#800000">Sim</strong></td> + <td align="center">{@code onResume()} <br/>ou<br/> {@code onStop()}</td> +</tr> + +<tr> + <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td> + <td>Chamado quando a atividade não está mais visível ao usuário. Isso +pode acontecer porque ela está sendo destruída ou porque outra atividade +(uma existente ou uma nova) foi retomada e está cobrindo-a. + <p>Seguido de {@code onRestart()} se a atividade +estiver voltando a interagir com o usuário +ou {@code onDestroy()} se estiver saindo.</p></td> + <td align="center"><strong style="color:#800000">Sim</strong></td> + <td align="center">{@code onRestart()} <br/>ou<br/> {@code onDestroy()}</td> +</tr> + +<tr> + <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy +onDestroy()}</code></td> + <td>Chamado antes de a atividade ser destruída. É a última chamada +que a atividade receberá. Pode ser chamado porque a atividade +está finalizando (alguém chamou <code>{@link android.app.Activity#finish + finish()}</code> nela) ou porque o sistema está destruindo temporariamente essa instância +da atividade para poupar espaço. É possível distinguir +entre essas duas situações com o método <code>{@link + android.app.Activity#isFinishing isFinishing()}</code>.</td> + <td align="center"><strong style="color:#800000">Sim</strong></td> + <td align="center"><em>nada</em></td> +</tr> +</tbody> +</table> + +<p>A coluna de nome "Eliminável depois de?" indica se o sistema pode ou não +eliminar o processo que hospeda a atividade a qualquer momento <em>após o método retornar</em> +sem executar outra linha de código da atividade. Estes três métodos são marcados como "sim": ({@link +android.app.Activity#onPause +onPause()}, {@link android.app.Activity#onStop onStop()} e {@link android.app.Activity#onDestroy +onDestroy()}). Como {@link android.app.Activity#onPause onPause()} é o primeiro +dos três, assim que a atividade é criada, {@link android.app.Activity#onPause onPause()} é +o último método que certamente será chamado antes que o processo <em>possa</em> ser eliminado — +se o sistema precisar recuperar memória em uma emergência, {@link +android.app.Activity#onStop onStop()} e {@link android.app.Activity#onDestroy onDestroy()} poderão +não ser chamados. Portanto, deve-se usar {@link android.app.Activity#onPause onPause()} para gravar +dados persistentes cruciais (como edições do usuário) no armazenamento. No entanto, deve-se sempre ser seletivo +acerca das informações que devem ser retidas durante {@link android.app.Activity#onPause onPause()} porque +qualquer procedimento de bloqueio nesse método bloqueará a transição para a próxima atividade e retardará +a experiência do usuário.</p> + +<p> Os métodos marcados como "Não" na coluna <b>Elimináveis</b> protegem o processo que hospeda +a atividade. evitando a eliminação dele no momento em que é chamado. Assim, uma atividade é eliminável +do momento em que {@link android.app.Activity#onPause onPause()} retorna ao momento em que +{@link android.app.Activity#onResume onResume()} é chamado. Ela não será eliminável novamente até que +{@link android.app.Activity#onPause onPause()} seja chamado e retorne novamente. </p> + +<p class="note"><strong>Observação:</strong> uma atividade tecnicamente não "eliminável”, por essa definição +na tabela 1, ainda pode ser eliminada pelo sistema — mas isso só ocorreria +em circunstâncias extremas, quando não houvesse outra opção. A possibilidade de uma atividade ser eliminada +é discutida em mais detalhes no documento <a href="{@docRoot}guide/components/processes-and-threads.html">Processos +e encadeamentos</a>.</p> + + +<h3 id="SavingActivityState">Gravação do estado da atividade</h3> + +<p>A introdução a <a href="#Lifecycle">Gerenciamento do ciclo de vida da atividade</a> menciona brevemente +que, +quando uma atividade é pausada ou interrompida, o estado da atividade é retido. Isso acontece porque +o objeto {@link android.app.Activity} continua mantido na memória quando a atividade está pausada +ou interrompida — todas as informações sobre seus membros e estado atual ainda estão ativas. Assim, todas as alterações +feitas pelo usuário dentro da atividade são retidas, de forma que, quando a atividade retornar +ao primeiro plano (quando é "retomada"), essas alterações ainda estejam lá.</p> + +<p>No entanto, quando o sistema destrói uma atividade para recuperar memória, o objeto {@link +android.app.Activity} é destruído, por isso o sistema não pode simplesmente retomá-la com seu estado +intacto. Em vez disso, o sistema tem que recriar o objeto {@link android.app.Activity} se o usuário +navegar de volta a ele. Ainda assim, o usuário não estará ciente +de que o sistema destruiu a atividade e recriou-a e, assim, provavelmente +esperará que a atividade esteja exatamente como antes. Nessa situação, para garantir que +as informações importantes sobre o estado da atividade sejam preservadas, implementa-se um método +adicional de retorno de chamada que permite salvar as informações sobre o estado da atividade: {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}.</p> + +<p>O sistema chama {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} +antes de deixar a mensagem vulnerável à destruição. O sistema passa a esse método +um {@link android.os.Bundle} no qual é possível salvar +informações de estado acerca da atividade, como pares nome-valor, usando métodos como {@link +android.os.Bundle#putString putString()} e {@link +android.os.Bundle#putInt putInt()}. Em seguida, se o sistema eliminar o processo +do aplicativo e o usuário voltar à atividade, o sistema recriará a atividade e passará +o {@link android.os.Bundle} a {@link android.app.Activity#onCreate onCreate()} e a {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}. Usando qualquer um desses métodos, +é possível extrair o estado salvo de {@link android.os.Bundle} e restaurar +o estado da atividade. Se não houver informações de estado a restaurar, o {@link +android.os.Bundle} passado será nulo (que é o caso quando a atividade é criada +pela primeira vez).</p> + +<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" /> +<p class="img-caption"><strong>Figura 2.</strong> As duas formas pelas quais uma atividade retorna ao foco +do usuário com seu estado intacto: ou a atividade é destruída e recriada em seguida — e ela deve restaurar +o estado salvo anteriormente —, ou a atividade é interrompida e retomada em seguida — e o estado dela +permanece intacto.</p> + +<p class="note"><strong>Observação:</strong> não há garantia nenhuma de que {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} será chamado antes de a atividade +ser destruída porque há casos em que não será necessário salvar o estado +(como quando o usuário sai da atividade usando o botão <em>Voltar</em>) porque o usuário está fechando +explicitamente +a atividade). Se o sistema chamar {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()}, ele o fará antes de {@link +android.app.Activity#onStop onStop()} e possivelmente antes de {@link android.app.Activity#onPause +onPause()}.</p> + +<p>No entanto, mesmo se você não fizer nada e não implementar {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}, parte do estado da atividade +será restaurada pela implementação padrão da classe {@link android.app.Activity} de {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Especificamente, a implementação +padrão chama o método {@link +android.view.View#onSaveInstanceState onSaveInstanceState()} correspondente para cada {@link +android.view.View} no layout, o que permite que cada vista forneça informações próprias sobre o que +deve ser salvo. Quase todo widget na estrutura do Android implementa esse método +conforme o necessário, de forma que qualquer alteração visível na IU seja automaticamente salva e restaurada +ao criar a atividade. Por exemplo, o widget {@link android.widget.EditText} salva qualquer texto +inserido pelo usuário e o widget {@link android.widget.CheckBox} salva independente +de verificação. O único trabalho necessário será fornecer um ID exclusivo (com +o atributo <a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>) para cada widget que for salvar seu estado. Se o widget não salvar nenhum ID, o sistema +não poderá salvar seu estado.</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<p>Para fazer com que uma vista deixe explicitamente de salvar seu estado, defina o atributo +{@link android.R.attr#saveEnabled android:saveEnabled} como {@code "false"} ou chame +o método {@link android.view.View#setSaveEnabled setSaveEnabled()}. Geralmente, não se deve +desativar isso, mas é possível caso se deseje restaurar o estado da IU da atividade de forma diferente.</p> +</div> +</div> + +<p>Embora a implementação padrão de {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} salve informações úteis sobre +a IU da atividade, talvez ainda seja necessário substituí-la para salvar informações adicionais. +Por exemplo: pode ser necessário salvar valores de membro alterados durante a vida da atividade (possivelmente +correlacionados a valores restaurados na IU, mas os membros que retêm esses valores de IU, por padrão, +não são restaurados).</p> + +<p>Como a implementação padrão de {@link +android.app.Activity#onSaveInstanceState onSaveInstanceState()} ajuda a salvar o estado da IU, +se o método for substituído para salvar informações de estado adicionais, deve-se sempre chamar a implementação +da superclasse de {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} +antes de fazer qualquer trabalho. Da mesma forma, deve-se também chamar a implementação da superclasse de {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} se ela for substituída para que +a implementação padrão possa restaurar estados da vista.</p> + +<p class="note"><strong>Observação:</strong> Como nem sempre {@link android.app.Activity#onSaveInstanceState +onSaveInstanceState()} é chamado, +deve-se usá-lo somente para registrar o estado temporário da atividade (o estado +da IU) — nunca se deve usá-lo para armazenar dados persistentes. Em vez disso, deve-se usar {@link +android.app.Activity#onPause onPause()} para armazenar dados persistentes (como dados que devem ser salvos +em um banco de dados) quando o usuário sair da atividade.</p> + +<p>Uma boa forma de testar a capacidade do aplicativo de restaurar seu estado é girar +o dispositivo para alterar a orientação da tela. Quando a orientação de tela muda, o sistema +destrói e recria a atividade para aplicar recursos alternativos que podem ser disponibilizados +para a nova configuração de tela. Por esse motivo somente, é muito importante que a atividade +restaure completamente seu estado quando for recriada porque os usuários normalmente giram a tela +ao usar aplicativos.</p> + + +<h3 id="ConfigurationChanges">Manipulação de alterações de configuração</h3> + +<p>Algumas configurações do dispositivo podem mudar em tempo de execução (como A orientação da tela, disponibilidade +do teclado e idioma). Quando ocorre uma alteração, o Android recria a atividade em execução +(o sistema chama {@link android.app.Activity#onDestroy} e, em seguida, chama {@link +android.app.Activity#onCreate onCreate()} imediatamente). Esse comportamento foi projetado +para ajudar o aplicativo a se adaptar a novas configurações recarregando-o automaticamente +com recursos alternativos fornecidos pelo programador (como diferentes layouts +para orientações e tamanhos de telas diferentes).</p> + +<p>Se você projetar adequadamente a atividade para manipular um reinício devido a uma alteração na orientação da tela +e restaurar o estado da atividade conforme descrito acima, o aplicativo será mais resiliente a outros +eventos inesperados no ciclo de vida da atividade.</p> + +<p>A melhor forma de manipular um reinício desse tipo +é salvar e restaurar o estado da atividade com {@link + android.app.Activity#onSaveInstanceState onSaveInstanceState()} e {@link +android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (ou com {@link +android.app.Activity#onCreate onCreate()}), conforme abordado na seção anterior.</p> + +<p>Para obter mais informações sobre alterações de configuração que podem ocorrer em tempo de execução e como manipulá-las, +leia o guia em <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Tratamento de +alterações em tempo de execução</a>.</p> + + + +<h3 id="CoordinatingActivities">Coordenação de atividades</h3> + + <p>Quando uma atividade inicia outra, ambas passam por transições no ciclo de vida. A primeira atividade +é pausada e interrompida (embora ela não seja interrompida se ainda estiver visível em segundo plano) enquanto a outra +atividade é criada. Caso essas atividades compartilhem dados salvos em disco ou em outro lugar, é importante +compreender que a primeira atividade não é totalmente interrompida antes da criação da segunda. +Em vez disso, o processo de iniciar a segunda se sobrepõe ao processo de interromper +a primeira.</p> + +<p>A ordem dos retornos de chamada do ciclo de vida é bem definida, especialmente quando as duas atividades estão +no mesmo processo e uma está iniciando a outra. A seguir há a ordem das operações que ocorrem quando a atividade A +inicia a atividade B: </p> + +<ol> +<li>O método {@link android.app.Activity#onPause onPause()} da atividade A é executado.</li> + +<li>Os métodos {@link android.app.Activity#onCreate onCreate()}, {@link +android.app.Activity#onStart onStart()} e {@link android.app.Activity#onResume onResume()} +da atividade B são executados em sequência (a atividade B agora tem o foco do usuário).</li> + +<li>Em seguida, se a atividade A não estiver mais visível na tela, seu método {@link +android.app.Activity#onStop onStop()} é executado.</li> +</ol> + + <p>Essa sequência previsível de retornos de chamada do ciclo de vida permite gerenciar a transição +de informações de uma atividade para outra. Por exemplo: se você for gravar em um banco de dados o momento em que +a primeira atividade é interrompida para que a atividade a seguir possa lê-lo, é preciso realizar a gravação +no banco de dados durante {@link android.app.Activity#onPause onPause()} e não durante {@link +android.app.Activity#onStop onStop()}.</p> + +<!-- +<h2>Beginner's Path</h2> + +<p>For more information about how Android maintains a history of activities and +enables user multitasking, continue with the <b><a +href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back +Stack</a></b> document.</p> +--> diff --git a/docs/html-intl/intl/pt-br/guide/components/bound-services.jd b/docs/html-intl/intl/pt-br/guide/components/bound-services.jd new file mode 100644 index 000000000000..aa024943160f --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/bound-services.jd @@ -0,0 +1,658 @@ +page.title=Serviços vinculados +parent.title=Serviços +parent.link=services.html +@jd:body + + +<div id="qv-wrapper"> +<ol id="qv"> +<h2>Neste documento</h2> +<ol> + <li><a href="#Basics">Conceitos básicos</a></li> + <li><a href="#Creating">Criação de um serviço vinculado</a> + <ol> + <li><a href="#Binder">Extensão da classe Binder</a></li> + <li><a href="#Messenger">Uso de um mensageiro</a></li> + </ol> + </li> + <li><a href="#Binding">Vinculação a um serviço</a></li> + <li><a href="#Lifecycle">Gerenciamento do ciclo de vida de um serviço vinculado</a></li> +</ol> + +<h2>Classes principais</h2> +<ol> + <li>{@link android.app.Service}</li> + <li>{@link android.content.ServiceConnection}</li> + <li>{@link android.os.IBinder}</li> +</ol> + +<h2>Exemplos</h2> +<ol> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code + RemoteService}</a></li> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code + LocalService}</a></li> +</ol> + +<h2>Veja também</h2> +<ol> + <li><a href="{@docRoot}guide/components/services.html">Serviços</a></li> +</ol> +</div> + + +<p>Um serviço vinculado é o servidor em uma interface servidor-cliente. Um serviço vinculado permite que componentes +(como atividades) sejam vinculados ao serviço, enviem solicitações, recebam respostas e até estabeleçam +comunicação entre processos (IPC). Um serviço vinculado, geralmente, vive somente enquanto serve +outro componente do aplicativo e não é executado em segundo plano indefinidamente.</p> + +<p>Este documento mostra como criar um serviço vinculado, inclusive como criar vínculos +com o serviço a partir de outros componentes do aplicativo. No entanto, você também deve consultar a documentação <a href="{@docRoot}guide/components/services.html">Serviços</a> para obter +informações adicionais sobre serviços de forma geral, por exemplo: como enviar notificações de um serviço, +como definir o serviço a ser executado em primeiro plano etc.</p> + + +<h2 id="Basics">Conceitos básicos</h2> + +<p>Um serviço vinculado é uma implementação da classe {@link android.app.Service} que permite +que outros aplicativos sejam vinculados e interajam com ele. Para fornecer a vinculação +a um serviço, você deve implementar o método de retorno de chamada {@link android.app.Service#onBind onBind()}. Este método +retorna um objeto {@link android.os.IBinder} que define a interface de programação +que os clientes podem usar para interagir com o serviço.</p> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h3>Vinculação com um serviço iniciado</h3> + +<p>Como discutido na documentação <a href="{@docRoot}guide/components/services.html">Serviços</a>, +é possível criar um serviço que já foi iniciado e vinculado. Ou seja, o serviço pode +ser iniciado chamando {@link android.content.Context#startService startService()}, que permite que ele +permaneça em execução indefinidamente e também permite que um cliente vincule-o chamando {@link +android.content.Context#bindService bindService()}. + <p>Se você permitir que o serviço seja iniciado e vinculado, então, quando ele +for iniciado, o sistema <em>não</em> o destruirá quando todos os clientes desfizerem a vínculo. Em vez disso, você deve +interromper o serviço explicitamente chamando {@link android.app.Service#stopSelf stopSelf()} ou {@link +android.content.Context#stopService stopService()}.</p> + +<p>Apesar de normalmente se implementar {@link android.app.Service#onBind onBind()} +<em>ou</em> {@link android.app.Service#onStartCommand onStartCommand()}, às vezes +é necessário implementar ambos. Por exemplo, um reprodutor de música pode achar útil permitir que o seu serviço +permaneça em execução indefinidamente, além de fornecer vinculação. Desta forma, uma atividade pode iniciar o serviço +para reproduzir algumas músicas e a música continuará em reprodução mesmo quando o usuário sair do aplicativo. Em seguida, quando o usuário +voltar ao aplicativo, a atividade poderá vincular-se ao serviço para retomar o controle da reprodução.</p> + +<p>Certifique-se de ler a seção sobre <a href="#Lifecycle">Gerenciamento do ciclo de vida de um serviço +vinculado</a> para obter mais informações sobre o ciclo de vida do serviço ao adicionar vinculação +a um serviço iniciado.</p> +</div> +</div> + +<p>Um cliente pode vincular-se ao serviço chamando {@link android.content.Context#bindService +bindService()}. Quando isto ocorre, é preciso fornecer uma implementação de {@link +android.content.ServiceConnection}, que monitora a conexão com o serviço. O método {@link +android.content.Context#bindService bindService()} retorna imediatamente sem um valor, +mas quando o sistema Android cria a conexão entre +o cliente e o serviço, ele chama {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} em {@link +android.content.ServiceConnection} para fornecer o {@link android.os.IBinder} +que o cliente pode usar para comunicar-se com o serviço.</p> + +<p>Vários clientes podem conectar-se ao serviço de uma vez. No entanto, o sistema chama o método +{@link android.app.Service#onBind onBind()} do serviço para recuperar o {@link android.os.IBinder} +somente quando o primeiro cliente é vinculado. Em seguida, o sistema entrega o mesmo {@link android.os.IBinder} +para quaisquer clientes adicionais que vincularem-se, sem chamar {@link android.app.Service#onBind onBind()} novamente.</p> + +<p>Quando o último cliente desvincular-se do serviço, o sistema destruirá o serviço +(a não ser que ele também seja iniciado por {@link android.content.Context#startService startService()}).</p> + +<p>Ao implementar o serviço vinculado, o mais importante é definir a interface +que o método de retorno de chamada {@link android.app.Service#onBind onBind()} retornará. Há poucas maneiras diferentes +de definir a interface {@link android.os.IBinder} do serviço e a +seção a seguir discute cada técnica.</p> + + + +<h2 id="Creating">Criação de um serviço vinculado</h2> + +<p>Ao criar um serviço que fornece vinculação, você deve fornecer um {@link android.os.IBinder} +que ofereça a interface de programação que os clientes podem usar para interagir com o serviço. Há três maneiras +possíveis de definir a interface:</p> + +<dl> + <dt><a href="#Binder">Extensão da classe Binder</a></dt> + <dd>Se o serviço for privado para o próprio aplicativo e for executado no mesmo processo que o cliente +(o que é comum), deve-se criar a interface estendendo-se a classe {@link android.os.Binder} +e retornando uma instância dela a partir de +{@link android.app.Service#onBind onBind()}. O cliente receberá {@link android.os.Binder} +e poderá usá-lo para acessar os métodos públicos disponíveis na implementação de {@link android.os.Binder} +ou até em {@link android.app.Service} diretamente. + <p>Esta é a técnica preferencial quando o serviço é meramente um trabalhador de segundo plano +para o aplicativo. O único motivo pelo qual não se criaria a interface desta maneira +é porque o serviço está sendo usado por outros aplicativos ou em processos separados.</dd> + + <dt><a href="#Messenger">Uso de um mensageiro</a></dt> + <dd>Caso precise que a interface funcione em diferentes processos, é possível +criar uma interface para o serviço com {@link android.os.Messenger}. Desta maneira, o serviço +define um {@link android.os.Handler} que responde a diferentes tipos de objetos {@link +android.os.Message}. Este {@link android.os.Handler} +é a base para {@link android.os.Messenger}, que pode então compartilhar um {@link android.os.IBinder} +com o cliente, permitindo que ele envie comandos ao serviço usando objetos {@link +android.os.Message}. Além disso, o cliente pode definir o próprio {@link android.os.Messenger} +para que o serviço possa enviar as mensagens de volta. + <p>Esta é a maneira mais simples de estabelecer comunicação entre processos (IPC), pois o {@link +android.os.Messenger} coloca todas as solicitações em fila em um único encadeamento para que você não precise +projetar o serviço de modo que seja seguro para encadeamentos.</p> + </dd> + + <dt>Uso de AIDL</dt> + <dd>O AIDL (Android Interface Definition Language, linguagem de definição de interface do Android) realiza todo o trabalho de decomposição de objetos +em primitivos para que o sistema operacional possa entendê-los e dispô-los em processos +para realizar a IPC. A técnica anterior, usando o {@link android.os.Messenger}, tem base em AIDL +como a estrutura fundamental. Como mencionado acima, o {@link android.os.Messenger} cria uma fila +de todas as solicitações de cliente em um único encadeamento para que o serviço receba uma solicitação por vez. Se, no entanto, +você quiser que o serviço lide com várias solicitações simultaneamente, é possível usar a AIDL +diretamente. Neste caso, o serviço deverá ser capaz de realizar vários encadeamentos e ser programado de forma segura para encadeamentos. + <p>Para usar a AIDL diretamente, deve-se +criar um arquivo {@code .aidl} que defina a interface de programação. As ferramentas SDK do Android +usam este arquivo para gerar uma classe abstrata que implemente a interface e lide com a IPC, +que pode ser estendida dentro do serviço.</p> + </dd> +</dl> + + <p class="note"><strong>Observação:</strong> a maioria dos aplicativos <strong>não deve</strong> usar a AIDL +para criar um serviço vinculado, pois isto requer capacidade de se trabalhar com encadeamentos múltiplos +e pode resultar em uma implementação mais complicada. Portanto, a AIDL não é adequada para a maioria dos aplicativos +e este documento não discute o seu uso para o serviço. Caso tenha certeza de que +precisa usar a AIDL diretamente, consulte a documentação +<a href="{@docRoot}guide/components/aidl.html">AIDL</a>.</p> + + + + +<h3 id="Binder">Extensão da classe Binder</h3> + +<p>Se o serviço for usado somente pelo aplicativo local e não precisar trabalhar entre processos, +então será possível implementar a própria classe {@link android.os.Binder} que fornece ao cliente +acesso direto aos métodos públicos no serviço.</p> + +<p class="note"><strong>Observação:</strong> isto funciona somente se o cliente e o serviço +estiverem no mesmo aplicativo e processo, o que é muito comum. Por exemplo, isto funcionaria bem para um +aplicativo de música que precise vincular uma atividade ao próprio serviço que está +reproduzindo música em segundo plano.</p> + +<p>Como configurar:</p> +<ol> + <li>No serviço, crie uma instância de {@link android.os.Binder} que: + <ul> + <li>contenha métodos públicos que o cliente possa chamar</li> + <li>retorne ao cliente a instância {@link android.app.Service}, que tenha métodos públicos +que ele possa chamar</li> + <li>ou retorne uma instância de outra classe hospedada pelo serviço com métodos públicos +que o cliente possa chamar</li> + </ul> + <li>Retorne esta instância de {@link android.os.Binder} a partir do método de retorno de chamada {@link +android.app.Service#onBind onBind()}.</li> + <li>No cliente, receba o {@link android.os.Binder} a partir do método de retorno de chamada {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()} +e faça chamadas para o serviços vinculados usando os métodos fornecidos.</li> +</ol> + +<p class="note"><strong>Observação:</strong> o motivo pelo qual o serviço e o cliente devem estar no mesmo aplicativo +é para que o cliente possa lançar o objeto retornado e chamar as APIs adequadamente. O serviço e o cliente +também devem estar no mesmo processo, pois esta técnica não possui +nenhuma ingerência entre processos.</p> + +<p>Por exemplo, a seguir há um serviço que fornece aos clientes acesso aos métodos no serviço +por meio de uma implementação de {@link android.os.Binder}:</p> + +<pre> +public class LocalService extends Service { + // Binder given to clients + private final IBinder mBinder = new LocalBinder(); + // Random number generator + private final Random mGenerator = new Random(); + + /** + * 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); + } +} +</pre> + +<p>O {@code LocalBinder} fornece o método {@code getService()} para que os clientes +recuperem a instância atual de {@code LocalService}. Isto permite que os clientes chamem métodos públicos +no serviço. Por exemplo, eles podem chamar {@code getRandomNumber()} a partir do serviço.</p> + +<p>Abaixo há uma atividade que vincula-se a {@code LocalService} e chama {@code getRandomNumber()} +quando um botão é pressionado:</p> + +<pre> +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) { + 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; + } + }; +} +</pre> + +<p>O exemplo acima mostra como o cliente vincula um serviço usando uma implementação +de {@link android.content.ServiceConnection} e o retorno de chamada {@link +android.content.ServiceConnection#onServiceConnected onServiceConnected()}. A próxima seção +fornece mais informações sobre este processo de vinculação ao serviço.</p> + +<p class="note"><strong>Observação:</strong> o exemplo acima não desfaz a vinculação explicitamente a partir do serviço, +mas todos os clientes devem fazê-lo no momento adequado (como quando a atividade pausa).</p> + +<p>Para obter mais códigos de exemplo, consulte a classe <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code +LocalService.java}</a> e a classe <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code +LocalServiceActivities.java}</a> em <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p> + + + + + +<h3 id="Messenger">Uso de um mensageiro</h3> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h4>Comparado ao AIDL</h4> + <p>Quando é necessário fazer uma IPC, usar o {@link android.os.Messenger} para a interface +é mais simples do que implementá-la com AIDL, pois o {@link android.os.Messenger} enfileira +todas as chamadas do serviço, enquanto que uma interface de AIDL pura envia solicitações simultâneas +ao serviço, que deve então lidar com vários encadeamentos.</p> + <p>Para a maioria dos aplicativos, o serviço não precisa realizar vários encadeamentos. Portanto, usar {@link +android.os.Messenger} permite que o serviço lide com uma chamada por vez. Caso seja importante +que o serviço realize vários encadeamentos, deve-se usar a <a href="{@docRoot}guide/components/aidl.html">AIDL</a> para definir a interface.</p> +</div> +</div> + +<p>Caso precise que o serviço comunique-se com processos remotos, é possível usar +o {@link android.os.Messenger} para fornecer a interface ao serviço. Esta técnica permite +estabelecer comunicação entre processos (IPC) sem precisar usar a AIDL.</p> + +<p>A seguir há um resumo sobre como usar um {@link android.os.Messenger}:</p> + +<ul> + <li>O serviço implementa um {@link android.os.Handler} que recebe um retorno de chamada +para cada chamada de um cliente.</li> + <li>O {@link android.os.Handler} é usado para criar um objeto {@link android.os.Messenger} +(que é uma referência para o {@link android.os.Handler}).</li> + <li>O {@link android.os.Messenger} cria um {@link android.os.IBinder} que o serviço +retorna aos clientes a partir de {@link android.app.Service#onBind onBind()}.</li> + <li>Os clientes usam {@link android.os.IBinder} para instanciar o {@link android.os.Messenger} +(que menciona o {@link android.os.Handler} do serviço), que usam para enviar objetos +{@link android.os.Message} para o serviço.</li> + <li>O serviço recebe cada {@link android.os.Message} em seu {@link +android.os.Handler} — especificamente, no método {@link android.os.Handler#handleMessage +handleMessage()}.</li> +</ul> + + +<p>Desta forma, não há "métodos" para o cliente chamar no serviço. Em vez disso, o cliente +envia "mensagens" (objetos {@link android.os.Message}) que o serviço recebe +no {@link android.os.Handler}.</p> + +<p>Abaixo há um exemplo simples de serviço que usa uma interface {@link android.os.Messenger}:</p> + +<pre> +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. + */ + 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(); + } +} +</pre> + +<p>Observe que o método {@link android.os.Handler#handleMessage handleMessage()} +no {@link android.os.Handler} é onde o serviço recebe a {@link android.os.Message} +e decide o que fazer, com base no membro {@link android.os.Message#what}.</p> + +<p>Tudo que o cliente precisa fazer é criar um {@link android.os.Messenger} com base no {@link +android.os.IBinder} retornado pelo serviço e enviar uma mensagem usando {@link +android.os.Messenger#send send()}. Por exemplo, a seguir há uma atividade simples que vincula-se +ao serviço e envia a mensagem {@code MSG_SAY_HELLO} a ele:</p> + +<pre> +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) { + // 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; + } + } +} +</pre> + +<p>Observe que este exemplo não mostra como o serviço pode responder ao cliente. Caso queira que o serviço responda, +é necessário criar um {@link android.os.Messenger} no cliente também. Em seguida, +quando o cliente receber o retorno de chamada de {@link android.content.ServiceConnection#onServiceConnected +onServiceConnected()}, ele enviará uma {@link android.os.Message} para o serviço que inclui +o {@link android.os.Messenger} no parâmetro {@link android.os.Message#replyTo} +do método {@link android.os.Messenger#send send()}.</p> + +<p>É possível ver um exemplo de como fornecer mensagens de duas vias nos exemplos <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code +MessengerService.java}</a> (serviço) e <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code +MessengerServiceActivities.java}</a> (cliente).</p> + + + + + +<h2 id="Binding">Vinculação a um serviço</h2> + +<p>Um componente de aplicativo (cliente) pode vincular-se a um serviço chamando +{@link android.content.Context#bindService bindService()}. O sistema Android, em seguida, +chama o método {@link android.app.Service#onBind +onBind()} do serviço, que retorna um {@link android.os.IBinder} para interagir com o serviço.</p> + +<p>A vinculação é assíncrona. {@link android.content.Context#bindService +bindService()} retorna imediatamente e <em>não</em> retorna o {@link android.os.IBinder} +ao cliente. Para receber {@link android.os.IBinder}, o cliente deve criar uma instância de {@link +android.content.ServiceConnection} e passá-la para {@link android.content.Context#bindService +bindService()}. O {@link android.content.ServiceConnection} inclui um método de retorno de chamada +que o sistema chama para entregar o {@link android.os.IBinder}.</p> + +<p class="note"><strong>Observação:</strong> somente atividades, serviços e provedores de conteúdo +podem vincular-se a um serviço — você <strong>não</strong> pode fazer isto a partir de um receptor de transmissão.</p> + +<p>Portanto, para vincular-se a um serviço a partir do cliente, deve-se: </p> +<ol> + <li>Implementar {@link android.content.ServiceConnection}. + <p>Sua implementação deve substituir dois métodos de retorno de chamada:</p> + <dl> + <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt> + <dd>O sistema chama isto para entregar o {@link android.os.IBinder} retornado +pelo método {@link android.app.Service#onBind onBind()} do serviço.</dd> + <dt>{@link android.content.ServiceConnection#onServiceDisconnected +onServiceDisconnected()}</dt> + <dd>O sistema Android chama isto quando a conexão ao serviço é perdida inesperadamente, + como quando o serviço apresenta problemas ou é fechado repentinamente. Isto <em>não</em> é chamado quando +o cliente desfaz o vínculo.</dd> + </dl> + </li> + <li>Chamar {@link +android.content.Context#bindService bindService()}, passando a implementação {@link +android.content.ServiceConnection}. </li> + <li>Quando o sistema chamar o método de retorno de chamada {@link android.content.ServiceConnection#onServiceConnected +onServiceConnected()}, é possível fazer chamadas para o serviço +usando os métodos definidos pela interface.</li> + <li>Para desconectar-se de um serviço, chamar {@link +android.content.Context#unbindService unbindService()}. + <p>Quando um cliente é destruído, o vínculo com o serviço acaba. No entanto, sempre desvincule-se +ao terminar a interação com o serviço ou quando a atividade pausar para que o serviço +possa ser encerrado enquanto não estiver em uso (os momentos adequados para vincular ou desvincular +são abordados mais abaixo).</p> + </li> +</ol> + +<p>Por exemplo, o fragmento a seguir conecta o cliente ao serviço criado acima +<a href="#Binder">estendendo a classe Binder</a> para que tudo que ele tenha que fazer seja lançar +o {@link android.os.IBinder} retornado para a classe {@code LocalService} e solicitar a instância de {@code +LocalService}:</p> + +<pre> +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; + } +}; +</pre> + +<p>Com este {@link android.content.ServiceConnection}, o cliente pode vincular-se a um serviço +passando-o para {@link android.content.Context#bindService bindService()}. Por exemplo:</p> + +<pre> +Intent intent = new Intent(this, LocalService.class); +bindService(intent, mConnection, Context.BIND_AUTO_CREATE); +</pre> + +<ul> + <li>O primeiro parâmetro de {@link android.content.Context#bindService bindService()} +é uma {@link android.content.Intent} que nomeia explicitamente o serviço que será vinculado (apesar de a intenção +poder ser implícita).</li> +<li>O segundo parâmetro é o objeto {@link android.content.ServiceConnection}.</li> +<li>O terceiro parâmetro é um sinalizador que indica as opções de vinculação. Geralmente, ele deve ser {@link +android.content.Context#BIND_AUTO_CREATE} para criar o serviço se não estiver ativo ainda. +Outros possíveis valores são {@link android.content.Context#BIND_DEBUG_UNBIND} +e {@link android.content.Context#BIND_NOT_FOREGROUND}, ou {@code 0} para nada.</li> +</ul> + + +<h3>Observações adicionais</h3> + +<p>A seguir há algumas observações importantes sobre a vinculação com um serviço:</p> +<ul> + <li>Deve-se sempre capturar exceções{@link android.os.DeadObjectException}, que são lançadas +quando a conexão apresenta erros. Esta é a única exceção lançada por métodos remotos.</li> + <li>Objetos são referências contadas em todos os processos. </li> + <li>Geralmente, alterna-se entre a vinculação e a desvinculação +durante os momentos crescentes e decrescentes do ciclo de vida do cliente. Por exemplo: + <ul> + <li>Caso precise interagir com o serviço enquanto a atividade estiver visível, +deve-se vincular durante {@link android.app.Activity#onStart onStart()} e desvincular durante {@link +android.app.Activity#onStop onStop()}.</li> + <li>Caso queira que a atividade receba mensagens mesmo quando for interrompida +em segundo plano, é possível vincular durante {@link android.app.Activity#onCreate onCreate()} +e desvincular durante {@link android.app.Activity#onDestroy onDestroy()}. Cuidado, pois isto significa que a atividade +precisa usar o serviço durante todo o tempo de execução (mesmo em segundo plano). +Portanto, se o serviço estiver em outro processo, o peso do processo será aumentado +e é mais provável que o sistema elimine-o.</li> + </ul> + <p class="note"><strong>Observação:</strong> geralmente, <strong>não</strong> se realiza o vínculo e o seu rompimento +durante o {@link android.app.Activity#onResume onResume()} e o {@link +android.app.Activity#onPause onPause()} da atividade, pois esses retornos de chamada ocorrem em todas as transições do ciclo de vida +e deve-se usar menos processamento possível nessas transações. Além disso, +se várias atividades no aplicativo vincularem-se ao mesmo serviço e houver uma transação entre duas +dessas atividades, o serviço poderá ser destruído e recriado à medida que a atividade desvincula-se, +durante a pausa, antes do próximo vínculo, durante a retomada (esta transição de atividade +para como as atividades coordenam os ciclos de vida é descrita no documento <a href="{@docRoot}guide/components/activities.html#CoordinatingActivities">Atividades</a> +).</p> +</ul> + +<p>Para obter mais códigos de exemplo mostrando como vincular a um serviço, consulte a classe <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code +RemoteService.java}</a> no <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p> + + + + + +<h2 id="Lifecycle">Gerenciamento do ciclo de vida de um serviço vinculado</h2> + +<p>Quando um serviço é desvinculado de todos os clientes, o sistema Android o destrói (a não ser que ele +também tenha sido inicializado com {@link android.app.Service#onStartCommand onStartCommand()}). Portanto, não é necessário +gerenciar o ciclo de vida do serviço se ele for puramente um serviço vinculado +— o sistema Android o gerencia com base nos vínculos com os clientes.</p> + +<p>No entanto, se você escolher implementar o método de retorno de chamada {@link android.app.Service#onStartCommand +onStartCommand()}, interrompa o serviço explicitamente, pois o serviço +já terá sido considerado como <em>iniciado</em>. Neste caso, o serviço permanece em execução até +ser interrompido com {@link android.app.Service#stopSelf()} ou outras chamadas de componente {@link +android.content.Context#stopService stopService()}, independente de vínculo +com qualquer cliente.</p> + +<p>Além disso, se o serviço for iniciado e aceitar vínculos, quando o sistema chamar +o método {@link android.app.Service#onUnbind onUnbind()}, será possível retornar +{@code true} opcionalmente se você quiser receber uma chamada de {@link android.app.Service#onRebind +onRebind()} na próxima vez em que um cliente vincular-se ao serviço (em vez de receber uma chamada de {@link +android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind +onRebind()} retorna vazio, mas o cliente ainda recebe {@link android.os.IBinder} +no retorno de chamada {@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}. +Abaixo, a figura 1 ilustra a lógica para este tipo de ciclo de vida.</p> + + +<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Figura 1.</strong> O ciclo de vida para um serviço que é iniciado +e também permite vínculos.</p> + + +<p>Para obter mais informações sobre o ciclo de vida de um serviço iniciado, consulte o documento <a href="{@docRoot}guide/components/services.html#Lifecycle">Serviços</a>.</p> + + + + diff --git a/docs/html-intl/intl/pt-br/guide/components/fragments.jd b/docs/html-intl/intl/pt-br/guide/components/fragments.jd new file mode 100644 index 000000000000..7b1acf9e3439 --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/fragments.jd @@ -0,0 +1,812 @@ +page.title=Fragmentos +parent.title=Atividades +parent.link=activities.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + <h2>Neste documento</h2> + <ol> + <li><a href="#Design">Filosofia do projeto</a></li> + <li><a href="#Creating">Criação de um fragmento</a> + <ol> + <li><a href="#UI">Adição de uma interface do usuário</a></li> + <li><a href="#Adding">Adição de um fragmento a uma atividade</a></li> + </ol> + </li> + <li><a href="#Managing">Gerenciamento de fragmentos</a></li> + <li><a href="#Transactions">Realização de operações com fragmentos</a></li> + <li><a href="#CommunicatingWithActivity">Comunicação com a atividade</a> + <ol> + <li><a href="#EventCallbacks">Criação de eventos de retornos de chamada para a atividade</a></li> + <li><a href="#ActionBar">Adição de itens à barra de ação</a></li> + </ol> + </li> + <li><a href="#Lifecycle">Tratamento do ciclo de vida dos fragmentos</a> + <ol> + <li><a href="#CoordinatingWithActivity">Coordenação com o ciclo de vida da atividade</a></li> + </ol> + </li> + <li><a href="#Example">Exemplo</a></li> + </ol> + + <h2>Classes principais</h2> + <ol> + <li>{@link android.app.Fragment}</li> + <li>{@link android.app.FragmentManager}</li> + <li>{@link android.app.FragmentTransaction}</li> + </ol> + + <h2>Veja também</h2> + <ol> + <li><a href="{@docRoot}training/basics/fragments/index.html">Construção de uma IU dinâmica com Fragmentos</a></li> + <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Compatibilidade com +tablets e celulares</a></li> + </ol> +</div> +</div> + +<p>Um {@link android.app.Fragment} representa o comportamento ou uma parte da interface do usuário em um +{@link android.app.Activity}. É possível combinar vários fragmentos em uma única atividade para compilar +uma IU de painéis múltiplos e reutilizar um fragmento em diversas atividades. Um fragmento +é como uma seção modular de uma atividade, que tem o próprio ciclo de vida, recebe os próprios eventos de entrada +e que pode ser adicionado ou removido com a atividade em execução (uma espécie de "sub-atividade" +que pode ser reutilizada em diferentes atividades).</p> + +<p>Um fragmento deve sempre ser embutido em uma atividade e o ciclo de vida dele +é diretamente impactado pelo ciclo de vida da atividade do host. Por exemplo, quando a atividade é pausada, todos os fragmentos +também são e, quando a atividade é destruída, todos os fragmentos também são. No entanto, enquanto +uma atividade estiver em execução (estiver no <em>estado do ciclo de vida</em> <a href="{@docRoot}guide/components/activities.html#Lifecycle">retomado</a>), é possível +manipular cada fragmento independentemente, como adicionar ou removê-los. Ao realizar tal operação com fragmentos, +também é possível adicioná-los a uma pilha de retorno que é gerenciada pela +atividade — cada entrada da pilha de retorno na atividade é um registro da operação de fragmento +que ocorreu. A pilha de retorno permite que o usuário inverta uma operação de fragmento (navegue ao contrário), +pressionando o botão <em>Voltar</em>.</p> + +<p>Ao adicionar um fragmento como parte do layout da atividade, ele viverá em um {@link +android.view.ViewGroup} dentro da hierarquia de vistas e o fragmento definirá o próprio +layout da vista. +É possível inserir um fragmento no layout, declarando-o no arquivo de layout +da atividade, como um elemento {@code <fragment>} ou a partir do código do aplicativo adicionando-o +a um {@link android.view.ViewGroup} existente. No entanto, não é necessário que um fragmento faça parte +do layout da atividade; também é possível usar um fragmento sem a IU como um trabalhador invisível +da atividade.</p> + +<p>Este documento descreve como compilar o aplicativo para usar fragmentos, +incluindo como os fragmentos podem manter seu estado ao serem adicionados à pilha de retorno da atividade, +como compartilhar eventos com a atividade e com outros fragmentos da atividade, como contribuir para a barra de ação +da atividade e muito mais.</p> + + +<h2 id="Design">Filosofia do projeto</h2> + +<p>O Android introduziu os fragmentos no Android 3.0 (API de nível 11), principalmente para suportar +mais projetos de IU flexíveis e dinâmicos em telas grandes, como em tablets. Como a tela de um tablet +é muito maior que a de um celular, há mais espaço para combinar +e alternar componentes da IU. Os fragmentos permitem tais projetos sem haver a necessidade de gerenciar +alterações complexas na hierarquia de vistas. Ao dividir o layout de uma atividade em fragmentos, é possível +modificar a aparência da atividade em tempo de execução e preservar essas alterações na pilha de retorno, +que é gerenciada por esta atividade.</p> + +<p>Por exemplo, um aplicativo de notícias pode usar um fragmento para exibir uma lista de artigos +na esquerda e outro fragmento para exibir um artigo na direita — ambos os fragmentos aparecem +em uma atividade, lado a lado, e cada fragmento possui o próprio conjunto de métodos de retorno de chamada do ciclo de vida e lidam +com os próprios eventos de entrada do usuário. Portanto, em vez de usar uma atividade para selecionar um artigo +e outra atividade para lê-lo, o usuário pode selecionar um artigo e lê-lo por completo dentro +da mesma atividade, como ilustrado no layout do tablet na figura 1.</p> + +<p>Você deve projetar cada fragmento como um componente modular e reutilizável da atividade. Ou seja, como cada fragmento +define seu próprio layout e comportamento com os próprios retornos de chamada do ciclo de vida, é possível +incluir um fragmento em várias atividades para poder projetá-lo para reutilização e evitar +a manipulação direta de um fragmento a partir de outro fragmento. Isto é especialmente importante porque +um fragmento modular permite alterar as combinações de fragmentos para tamanhos de tela diferentes. Ao projetar o aplicativo +para ser compatível com tablets e celulares, você poderá reutilizar os fragmentos em diferentes configurações +de layout para otimizar a experiência do usuário com base no espaço de tela disponível. Por exemplo, +em um celular, talvez seja necessário separar os fragmentos para fornecer uma IU de painel único +quando mais de um não se encaixar dentro da mesma atividade.</p> + +<img src="{@docRoot}images/fundamentals/fragments.png" alt="" /> +<p class="img-caption"><strong>Figura 1.</strong> Um exemplo de como dois módulos de IU definidos +pelos fragmentos podem ser combinados em uma atividade de um projeto para tablet mas separados +em um projeto para celular.</p> + +<p>Por exemplo, — continuando com o exemplo do aplicativo de notícias — o aplicativo pode embutir +dois fragmentos na <em>atividade A</em>, quando executado em um dispositivo do tamanho de um tablet. No entanto, +em uma tela de tamanho de celular, não há espaço suficiente para ambos os fragmentos, então a <em>atividade A</em> inclui +somente o fragmento da lista de artigos e, quando o usuário seleciona um artigo, ele inicia +a <em>atividade B</em>, que inclui o segundo fragmento para ler o artigo. Portanto, o aplicativo +é compatível com tablets e celulares através da reutilização dos fragmentos em combinações diferentes, como ilustrado +na figura 1.</p> + +<p>Para obter mais informações sobre o projeto de aplicativos com diferentes combinações de fragmentos +para configurações de tela diferentes, consulte o guia <a href="{@docRoot}guide/practices/tablets-and-handsets.html">Compatibilidade com tablets e celulares</a>.</p> + + + +<h2 id="Creating">Criação de um fragmento</h2> + +<div class="figure" style="width:327px"> +<img src="{@docRoot}images/fragment_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Figura 2.</strong> O ciclo de vida de um fragmento +(enquanto sua atividade está em execução).</p> +</div> + +<p>Para criar um fragmento, é preciso criar uma subclasse de {@link android.app.Fragment} (ou uma respectiva +subclasse existente). A classe {@link android.app.Fragment} tem um código que é muito parecido +com o de uma {@link android.app.Activity}. Ele contém métodos de retorno de chamada semelhantes aos de uma atividade, +como {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()}, +{@link android.app.Fragment#onPause onPause()} e {@link android.app.Fragment#onStop onStop()}. Na verdade, +caso esteja convertendo um aplicativo do Android existente para usar os fragmentos, basta mover +o código dos métodos de retorno de chamada da atividade para os respectivos métodos de retorno de chamada +do fragmento.</p> + +<p>Geralmente, deve-se implementar pelo menos os seguintes métodos de ciclo de vida:</p> + +<dl> + <dt>{@link android.app.Fragment#onCreate onCreate()}</dt> + <dd>O sistema o chama ao criar o fragmento. Dentro da implementação, +deve-se inicializar os componentes essenciais do fragmento que deseja-se reter quando o fragmento +for pausado ou interrompido e, em seguida, retomado.</dd> + <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt> + <dd>O sistema chama isto quando é o momento de o fragmento desenhar a interface do usuário +pela primeira vez. Para desenhar uma IU para o fragmento, você deve retornar uma {@link android.view.View} +deste método, que é a raiz do layout do fragmento. É possível retornar como nulo se o fragmento +não fornecer uma IU.</dd> + <dt>{@link android.app.Activity#onPause onPause()}</dt> + <dd>O sistema chama esse método como o primeiro indício de que o usuário está saindo +do fragmento (embora não seja sempre uma indicação de que o fragmento está sendo destruído). É quando geralmente +deve-se confirmar qualquer alteração que deva se manter além da sessão atual do usuário (porque +o usuário pode não retornar).</dd> +</dl> + +<p>A maioria dos aplicativos deve implementar pelo menos três destes métodos para cada fragmento, +mas há vários outros métodos de retorno de chamada que você deve usar para lidar com diversos estágios +do ciclo de vida do fragmento. Todos os métodos de retorno de chamada do ciclo de vida são abordados com mais detalhes na seção +<a href="#Lifecycle">Tratamento do ciclo de vida dos fragmentos</a>.</p> + + +<p>Há também algumas subclasses que você pode querer estender, em vez de a classe {@link +android.app.Fragment} de base:</p> + +<dl> + <dt>{@link android.app.DialogFragment}</dt> + <dd>Exibe uma caixa de diálogo flutuante. Usar esta classe para criar uma caixa de diálogo é uma boa alternativa +para usar métodos auxiliares das caixas de diálogo na classe {@link android.app.Activity}, +pois é possível incorporar uma caixa de diálogo de fragmento na pilha de retorno dos fragmentos gerenciados pela atividade, +permitindo que o usuário retorne a um fragmento dispensado.</dd> + + <dt>{@link android.app.ListFragment}</dt> + <dd>Exibe uma lista de itens que são gerenciados por um adaptador (como um {@link +android.widget.SimpleCursorAdapter}), semelhante à {@link android.app.ListActivity}. Ele fornece vários métodos +para gerenciar uma vista de lista, como o retorno de chamada {@link +android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} +para lidar com eventos de clique.</dd> + + <dt>{@link android.preference.PreferenceFragment}</dt> + <dd>Exibe uma hierarquia de objetos {@link android.preference.Preference} como uma lista, +parecido com {@link android.preference.PreferenceActivity}. Isto é útil ao criar uma atividade +de "configurações" para o aplicativo.</dd> +</dl> + + +<h3 id="UI">Adição de uma interface do usuário</h3> + +<p>Um fragmento é geralmente usado como parte de uma interface do usuário da atividade e contribui +para a atividade com seu próprio layout.</p> + +<p>Para fornecer um layout para um fragmento, você deve implementar o método de retorno de chamada {@link +android.app.Fragment#onCreateView onCreateView()}, que o sistema Android chama +no momento em que o fragmento deve desenhar o layout. A implementação deste método deve retornar +uma {@link android.view.View}, que é a raiz do layout do fragmento.</p> + +<p class="note"><strong>Observação:</strong> se o fragmento for uma subclasse de {@link +android.app.ListFragment}, a implementação padrão retornará uma {@link android.widget.ListView} +de {@link android.app.Fragment#onCreateView onCreateView()}, então não será necessário implementá-lo.</p> + +<p>Para retornar um layout de {@link +android.app.Fragment#onCreateView onCreateView()}, é possível inflá-lo a partir de um <a href="{@docRoot}guide/topics/resources/layout-resource.html">recurso de layout</a> definido no XML. Para ajudar +a fazer isto, o {@link android.app.Fragment#onCreateView onCreateView()} fornece +um objeto {@link android.view.LayoutInflater}.</p> + +<p>Por exemplo, a seguir há uma subclasse de {@link android.app.Fragment} que carrega um layout +do arquivo {@code example_fragment.xml}:</p> + +<pre> +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); + } +} +</pre> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h3>Criação de um layout</h3> + <p>No exemplo acima, {@code R.layout.example_fragment} é uma referência para um recurso de layout +chamado {@code example_fragment.xml}, salvo nos recursos do aplicativo. Para obter informações sobre +como criar um layout no XML, consulte a documentação <a href="{@docRoot}guide/topics/ui/index.html">Interface do usuário</a> +.</p> +</div> +</div> + +<p>O parâmetro {@code container} passado para {@link android.app.Fragment#onCreateView +onCreateView()} é o pai de {@link android.view.ViewGroup} (do layout da atividade) +em que o layout do fragmento +será inserido. O parâmetro {@code savedInstanceState} é um {@link android.os.Bundle} +que fornece dados sobre a instância anterior do fragmento, se o fragmento estiver sendo retomado +(a restauração de estado é abordada mais detalhadamente na seção <a href="#Lifecycle">Tratamento do ciclo +de vida dos fragmentos</a>).</p> + +<p>O método {@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} +usa três argumentos:</p> +<ul> + <li>O ID de recurso do layout que você quer inflar.</li> + <li>O {@link android.view.ViewGroup} que será pai do layout inflado. Passar o {@code +container} é importante para que o sistema aplique os parâmetros de layout à vista raiz +do layout inflado, especificado pela vista pai em que está ocorrendo.</li> + <li>Um booleano que indica se o layout inflado deve ser anexado a {@link +android.view.ViewGroup} (o segundo parâmetro) durante a inflação (neste caso, +isto é falso, pois o sistema já está inserindo o layout inflado no {@code +container} — retornar como verdadeiro criaria um grupo de vistas redundante no layout final).</li> +</ul> + +<p>Este é o modo de criar um fragmento que fornece um layout. A seguir, +é preciso adicionar o fragmento à atividade.</p> + + + +<h3 id="Adding">Adição de um fragmento a uma atividade</h3> + +<p>Geralmente, um fragmento contribui com a atividade do host com uma parte da IU, que é embutida como parte +da hierarquia de vistas geral da atividade. Há duas formas de adicionar um fragmento ao layout +da atividade:</p> + +<ul> + <li><b>Declarar o fragmento dentro do arquivo de layout da atividade.</b> +<p>Neste caso, +é possível especificar as propriedades do layout para o fragmento como se fosse uma vista. Por exemplo, a seguir há o arquivo de layout +para uma atividade com dois fragmentos:</p> +<pre> +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <fragment android:name="com.example.news.ArticleListFragment" + android:id="@+id/list" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="match_parent" /> + <fragment android:name="com.example.news.ArticleReaderFragment" + android:id="@+id/viewer" + android:layout_weight="2" + android:layout_width="0dp" + android:layout_height="match_parent" /> +</LinearLayout> +</pre> + <p>O atributo {@code android:name} em {@code <fragment>} especifica a classe {@link +android.app.Fragment} a instanciar no layout.</p> + +<p>Quando o sistema cria este layout de atividade, ele instancia cada fragmento especificado +no layout e chama o método {@link android.app.Fragment#onCreateView onCreateView()} para cada um +para recuperar o layout de cada fragmento. O sistema insere a {@link android.view.View} retornada +pelo fragmento diretamente no lugar do elemento {@code <fragment>}.</p> + +<div class="note"> + <p><strong>Observação:</strong> cada fragmento requer um identificador único +que o sistema possa usar para restaurá-lo se a atividade for reiniciada (e que possa ser usado +para capturar o fragmento para realizar operações, como a remoção). Há três maneiras de fornecer +um ID para um fragmento:</p> + <ul> + <li>Fornecer o atributo {@code android:id} com um ID único.</li> + <li>Fornecer o atributo {@code android:tag} com uma string única.</li> + <li>Caso não forneça nenhuma das alternativas anteriores, o sistema usará o ID da vista +do recipiente.</li> + </ul> +</div> + </li> + + <li><b>Ou adicionar programaticamente o fragmento a um {@link android.view.ViewGroup} existente.</b> +<p>A qualquer momento, enquanto a atividade está em execução, é possível adicionar fragmentos ao layout da atividade. Você precisa +apenas especificar um {@link +android.view.ViewGroup} para posicionar o fragmento.</p> + <p>Para realizar operações de fragmentos na atividade (como adicionar, remover ou substituir +um fragmento), você deve usar APIs de {@link android.app.FragmentTransaction}. É possível adquirir +uma instância de {@link android.app.FragmentTransaction} da {@link android.app.Activity} desta maneira:</p> + +<pre> +FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()} +FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()}; +</pre> + +<p>É possível adicionar um fragmento usando o método {@link +android.app.FragmentTransaction#add(int,Fragment) add()}, especificando o fragmento que será adicionado +e a vista em que será inserido. Por exemplo:</p> + +<pre> +ExampleFragment fragment = new ExampleFragment(); +fragmentTransaction.add(R.id.fragment_container, fragment); +fragmentTransaction.commit(); +</pre> + + <p>O primeiro argumento passado para {@link android.app.FragmentTransaction#add(int,Fragment) add()} +é {@link android.view.ViewGroup}, onde o fragmento deve ser colocado, especificado +pelo ID de recurso e o segundo parâmetro é o fragmento a ser adicionado.</p> + <p>Ao realizar as alterações +com {@link android.app.FragmentTransaction}, +deve-se chamar{@link android.app.FragmentTransaction#commit} para que as alterações entrem em vigor.</p> + </li> +</ul> + + +<h4 id="AddingWithoutUI">Adição de um fragmento sem IU</h4> + +<p>O exemplo acima mostra como adicionar um fragmento à atividade para fornecer uma IU. No entanto, +é possível também usar um fragmento para fornecer o comportamento de segundo plano para a atividade sem apresentar +IU adicional.</p> + +<p>Para adicionar um fragmento sem uma IU, adicione o fragmento da atividade usando {@link +android.app.FragmentTransaction#add(Fragment,String)} (fornecendo uma "tag" de string única +para o fragmento, em vez de um ID de vista). Isto adiciona o fragmento, mas, como ele não está associado +a uma vista no layout da atividade, não recebe uma chamada de {@link +android.app.Fragment#onCreateView onCreateView()}. Portanto, não é necessário implementar este método.</p> + +<p>Fornecer uma tag de string para o fragmento não é algo estrito para fragmentos que não sejam de IU — é possível também +fornecer tags de string para fragmentos que possuam uma IU — mas, se o fragmento não possuir uma IU, +a tag de string é a única maneira de identificá-lo. Caso queira obter o fragmento da atividade posteriormente, +você precisará usar {@link android.app.FragmentManager#findFragmentByTag +findFragmentByTag()}.</p> + +<p>Para ver uma atividade de exemplo que usa um fragmento como um trabalhador de segundo plano, sem uma IU, consulte o exemplo de {@code +FragmentRetainInstance.java}, incluso nos exemplos do SDK (disponibilizados pelo +Android SDK Manager) e localizado no sistema como +<code><sdk_root>/APIDemos/app/src/main/java/com/example/android/apis/app/FragmentRetainInstance.java</code>.</p> + + + +<h2 id="Managing">Gerenciamento de fragmentos</h2> + +<p>Para gerenciar os fragmentos na atividade, você precisa usar {@link android.app.FragmentManager}. Para adquiri-lo, +chame {@link android.app.Activity#getFragmentManager()} a partir da atividade.</p> + +<p>Algumas das coisas que você pode fazer com {@link android.app.FragmentManager} incluem:</p> + +<ul> + <li>Adquirir fragmentos existentes na atividade, com {@link +android.app.FragmentManager#findFragmentById findFragmentById()} (para fragmentos que forneçam uma IU +no layout da atividade) ou {@link android.app.FragmentManager#findFragmentByTag +findFragmentByTag()} (para fragmentos que forneçam ou não uma IU).</li> + <li>Retire os fragmentos da pilha de retorno com {@link +android.app.FragmentManager#popBackStack()} (simulando um comando de <em>Voltar</em> do usuário).</li> + <li>Registre uma escuta para as alterações na pilha de retorno com {@link +android.app.FragmentManager#addOnBackStackChangedListener addOnBackStackChangedListener()}.</li> +</ul> + +<p>Para obter mais informações sobre esses e outros métodos, consulte a documentação da classe {@link +android.app.FragmentManager}.</p> + +<p>Como demonstrado na seção anterior, é possível usar o {@link android.app.FragmentManager} +para abrir uma {@link android.app.FragmentTransaction}, que permite realizar operações, +como adicionar e remover fragmentos.</p> + + +<h2 id="Transactions">Realização de operações com fragmentos</h2> + +<p>Um grande recurso fornecido por fragmentos em atividades é a possibilidade de adicionar, remover, substituir +e realizar outras ações com eles em resposta à interação do usuário. Cada conjunto de alterações que forem realizadas +na atividade é chamado de operação e podem ser feitas usando APIs em {@link +android.app.FragmentTransaction}. Também é possível salvar cada operação em uma pilha de retorno gerenciada pela atividade, +permitindo que o usuário navegue inversamente por meio de alterações de fragmento (semelhante à navegação +inversa por meio de atividades).</p> + +<p>É possível adquirir uma instância de {@link android.app.FragmentTransaction} a partir do {@link +android.app.FragmentManager} da seguinte forma:</p> + +<pre> +FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()}; +FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()}; +</pre> + +<p>Cada operação é um conjunto de alterações que você deseja realizar ao mesmo tempo. É possível definir +todas as alterações desejadas para uma operação usando métodos como {@link +android.app.FragmentTransaction#add add()}, {@link android.app.FragmentTransaction#remove remove()} +e {@link android.app.FragmentTransaction#replace replace()}. Em seguida, para aplicar a operação +à atividade, deve-se chamar {@link android.app.FragmentTransaction#commit()}.</p> +</dl> + +<p>Antes de chamar {@link +android.app.FragmentTransaction#commit()}, no entanto, você pode querer chamar {@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} para adicionar a operação +a uma pilha de retorno de operações de fragmentos. A pilha de retorno é gerenciada pela atividade +e permite que o usuário retorne ao estado anterior do fragmento, ao pressionar o botão <em>Voltar</em>.</p> + +<p>Por exemplo, a seguir é apresentado o modo de substituir um fragmento por outro e preservar +o estado anterior da pilha de retorno:</p> + +<pre> +// 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(); +</pre> + +<p>Neste exemplo, {@code newFragment} substitui qualquer fragmento (se houver) que estiver +no recipiente do layout identificado pelo ID {@code R.id.fragment_container}. Ao chamar {@link +android.app.FragmentTransaction#addToBackStack addToBackStack()}, a operação de substituição +é salva na pilha de retorno para que o usuário possa reverter a operação +e voltar ao fragmento anterior pressionando o botão <em>Voltar</em>.</p> + +<p>Se você adicionar várias alterações à operação (como outro {@link +android.app.FragmentTransaction#add add()} ou {@link android.app.FragmentTransaction#remove +remove()}) e chamar {@link +android.app.FragmentTransaction#addToBackStack addToBackStack()}, todas as alterações aplicadas +antes de chamar {@link android.app.FragmentTransaction#commit commit()} serão adicionadas +à pilha de retorno como uma única operação e o botão <em>Voltar</em> reverterá todas elas juntas.</p> + +<p>A ordem em que você adicionar as alterações em {@link android.app.FragmentTransaction} não importa, +exceto que:</p> +<ul> + <li>Você deve chamar {@link android.app.FragmentTransaction#commit()} por último</li> + <li>Caso esteja adicionando vários fragmentos ao mesmo recipiente, a ordem em que +adicioná-los determina a ordem em que eles aparecerão na hierarquia de vistas</li> +</ul> + +<p>Caso você não chame {@link android.app.FragmentTransaction#addToBackStack(String) +addToBackStack()} ao realizar uma operação que remove um fragmento, este fragmento +será destruído quando a operação for realizada e o usuário não poderá navegar de volta a ele. Considerando que, +se você não chamar {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} +ao remover um fragmento, o fragmento será <em>interrompido</em> e será retomado se o usuário +navegar de volta.</p> + +<p class="note"><strong>Dica:</strong> para cada operação de fragmento, é possível aplicar uma animação +de transição, chamando {@link android.app.FragmentTransaction#setTransition setTransition()} +antes da realização.</p> + +<p>Chamar {@link android.app.FragmentTransaction#commit()} não realiza a operação +imediatamente. Em vez disso, o parâmetro agenda a execução no encadeamento da IU da atividade (o encadeamento “main”, ou principal) +assim que possível. Se necessário, no entanto, é possível chamar {@link +android.app.FragmentManager#executePendingTransactions()} a partir do encadeamento da IU para executar imediatamente +as operações enviadas por {@link android.app.FragmentTransaction#commit()}. Tal medida, geralmente, +não é necessária, a não ser que a operação represente uma dependência para trabalhos em outros encadeamentos.</p> + +<p class="caution"><strong>Atenção:</strong> É possível realizar uma operação usando {@link +android.app.FragmentTransaction#commit commit()} somente antes da atividade <a href="{@docRoot}guide/components/activities.html#SavingActivityState">salvar +seu estado</a> (quando o usuário deixa a atividade). Caso tente efetivas as alterações após este ponto, +uma exceção será lançada. Isto acontece porque o estado após a efetivação pode ser perdido se a atividade +precisar ser restaurada. Para situações em que não haja problema em perder a efetivação, use {@link +android.app.FragmentTransaction#commitAllowingStateLoss()}.</p> + + + + +<h2 id="CommunicatingWithActivity">Comunicação com a atividade</h2> + +<p>Apesar de {@link android.app.Fragment} ser implementado como um objeto independente +de uma {@link android.app.Activity} e poder ser usado dentro de várias atividades, uma dada instância +de um fragmento é diretamente vinculada à atividade que o contém.</p> + +<p>Especificamente, o fragmento pode acessar a instância {@link android.app.Activity} com {@link +android.app.Fragment#getActivity()} e realizar facilmente tarefas como encontrar uma vista +no layout da atividade:</p> + +<pre> +View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list); +</pre> + +<p>Do mesmo modo, a atividade pode chamar métodos no fragmento adquirindo uma referência +para o {@link android.app.Fragment} a partir do {@link android.app.FragmentManager} usando {@link +android.app.FragmentManager#findFragmentById findFragmentById()} ou {@link +android.app.FragmentManager#findFragmentByTag findFragmentByTag()}. Por exemplo:</p> + +<pre> +ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment); +</pre> + + +<h3 id="EventCallbacks">Criação de retornos de chamada de evento para a atividade</h3> + +<p>Em alguns casos, um fragmento que compartilhe eventos com a atividade pode ser necessário. Uma boa maneira de fazer isto +é definir uma interface de retorno de chamada dentro do fragmento e solicitar que a atividade do host +implemente-a. Quando a atividade recebe um retorno de chamada por meio da interface, ela pode compartilhar as informações +com outros fragmentos no layout conforme necessário.</p> + +<p>Por exemplo, se um aplicativo de notícias em uma atividade tiver dois fragmentos — um para exibir uma lista +de artigos (fragmento A) e outro para exibir um artigo (fragmento B) — então o fragmento A +deve informar à atividade quando um item de lista é selecionado para que ela possa instruir o fragmento B a exibir o artigo. Neste caso, + a interface {@code OnArticleSelectedListener} é declarada dentro do fragmento A:</p> + +<pre> +public static class FragmentA extends ListFragment { + ... + // Container Activity must implement this interface + public interface OnArticleSelectedListener { + public void onArticleSelected(Uri articleUri); + } + ... +} +</pre> + +<p>Portanto, a atividade que hospeda o fragmento implementa a interface {@code OnArticleSelectedListener} +e suspende +{@code onArticleSelected()} para notificar o fragmento B do evento do fragmento A. Para garantir +que a atividade do host implemente esta interface, o método de retorno de chamada de {@link +android.app.Fragment#onAttach onAttach()} do fragmento A (que o sistema chama ao adicionar +o fragmento à atividade) instanciará {@code OnArticleSelectedListener} +lançando a {@link android.app.Activity}, que é passada para {@link android.app.Fragment#onAttach +onAttach()}:</p> + +<pre> +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"); + } + } + ... +} +</pre> + +<p>Se a atividade não implementar a interface, o fragmento lançará +{@link java.lang.ClassCastException}. +Se for bem-sucedida, o membro {@code mListener} reterá uma referência da implementação da atividade +de {@code OnArticleSelectedListener}, para que o fragmento A possa compartilhar os eventos com a atividade +chamando métodos definidos pela interface {@code OnArticleSelectedListener}. Por exemplo, se o fragmento A +for uma extensão de {@link android.app.ListFragment}, sempre +que o usuário clicar em um item de lista, o sistema chamará {@link android.app.ListFragment#onListItemClick +onListItemClick()} no fragmento que, em seguida, chamará {@code onArticleSelected()} para compartilhar +o evento com a atividade:</p> + +<pre> +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.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id); + // Send the event and Uri to the host activity + mListener.onArticleSelected(noteUri); + } + ... +} +</pre> + +<p>O parâmetro {@code id} passado para {@link +android.app.ListFragment#onListItemClick onListItemClick()} é o ID da linha do item clicado +que a atividade (ou outro fragmento) usa para resgatar o artigo do {@link +android.content.ContentProvider} do aplicativo.</p> + +<p><!--To see a complete implementation of this kind of callback interface, see the <a +href="{@docRoot}resources/samples/NotePad/index.html">NotePad sample</a>. -->Mais informações sobre +como usar o provedor de conteúdo estão disponíveis na documentação <a href="{@docRoot}guide/topics/providers/content-providers.html">Provedores de conteúdo</a>.</p> + + + +<h3 id="ActionBar">Adição de itens à barra de ação</h3> + +<p>Os fragmentos podem contribuir com itens de menu para o <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">menu de opções</a> da atividade (e, consequentemente, para a <a href="{@docRoot}guide/topics/ui/actionbar.html">barra de ação</a>) implementando +{@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}. Para que este método +receba chamadas, no entanto, você deve chamar {@link +android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()} durante {@link +android.app.Fragment#onCreate(Bundle) onCreate()} para indicar que o fragmento +gostaria de adicionar itens ao menu de opções (caso contrário, o fragmento não receberá uma chamada +para {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}).</p> + +<p>Quaisquer itens adicionados ao menu de opções do fragmento são anexados +aos itens de menu existentes. O fragmento também recebe retornos de chamada para {@link +android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} quando um item de menu +é selecionado.</p> + +<p>Também é possível registrar uma vista no layout do fragmento para fornecer um menu de contexto chamando {@link +android.app.Fragment#registerForContextMenu(View) registerForContextMenu()}. Quando o usuário +abre o menu de contexto, o fragmento recebe uma chamada de {@link +android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo) +onCreateContextMenu()}. Quando o usuário seleciona um item, o fragmento recebe uma chamada de {@link +android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()}.</p> + +<p class="note"><strong>Observação:</strong> apesar de o fragmento receber um retorno de chamada selecionado no item +para cada item de menu que adiciona, a atividade é a primeira a receber o respectivo retorno de chamada quando o usuário +seleciona um item de menu. Se a implementação da atividade do retorno de chamada selecionado no item não +lida com o item selecionado, o evento é passado para o retorno de chamada do fragmento. Isto é verdadeiro +para o menu de opções e os menus de contexto.</p> + +<p>Para obter mais informações sobre menus, consulte os guias do desenvolvedor <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> e <a href="{@docRoot}guide/topics/ui/actionbar.html">Barra de ação</a>.</p> + + + + +<h2 id="Lifecycle">Tratamento do ciclo de vida dos fragmentos</h2> + +<div class="figure" style="width:350px"> +<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Figura 3.</strong> O efeito do ciclo de vida da atividade no ciclo de vida +do fragmento.</p> +</div> + +<p>Gerenciar o ciclo de vida de um fragmento é muito parecido com gerenciar o ciclo de vida de uma atividade. Como uma atividade, +um fragmento pode existir em três estados:</p> + +<dl> + <dt><i>Retomado</i></dt> + <dd>O fragmento é visível na atividade em execução.</dd> + + <dt><i>Pausado</i></dt> + <dd>Outra atividade está em primeiro plano, mas a atividade em que este fragmento +vive ainda está visível (a atividade de primeiro plano é parcialmente transparente +ou não cobre a tela inteira).</dd> + + <dt><i>Interrompido</i></dt> + <dd>O fragmento não é visível. A atividade do host foi interrompida +ou o fragmento foi removido da atividade mas adicionado à pilha de retorno. Um fragmento interrompido +ainda está vivo (todas as informações do membro e de estado estão retidas no sistema). No entanto, +não está mais visível e será eliminado se a atividade também for.</dd> +</dl> + +<p>Além disso, como uma atividade, é possível reter o estado de um fragmento usando um {@link +android.os.Bundle}, caso o processo da atividade seja eliminado e você precise restaurar +o estado do fragmento quando a atividade for recriada. É possível salvar o estado durante o retorno de chamada {@link +android.app.Fragment#onSaveInstanceState onSaveInstanceState()} do fragmento e restaurá-lo +durante {@link android.app.Fragment#onCreate onCreate()}, {@link +android.app.Fragment#onCreateView onCreateView()} ou {@link +android.app.Fragment#onActivityCreated onActivityCreated()}. Para obter mais informações sobre +como salvar o estado, consulte a documentação <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Atividades</a> +.</p> + +<p>A diferença mais significante entre o ciclo de vida de uma atividade e de um fragmento +é o armazenamento em suas respectivas pilhas de retorno. Por padrão, uma atividade é colocada de volta na pilha de retorno de atividades, +que é gerenciada pelo sistema, quando interrompida (para que o usuário possa navegar +a ela com o botão <em>Voltar</em>, como discutido em <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tarefas e pilha de retorno</a>). +No entanto, um fragmento é posicionado em uma pilha de retorno gerenciada pela atividade do host somente +ao solicitar explicitamente que a instância seja salva chamando {@link +android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} durante uma operação +que remove o fragmento.</p> + +<p>Caso contrário, gerenciar o ciclo de vida do fragmento é muito semelhante a gerenciar +o ciclo de vida da atividade. Portanto, as mesmas práticas para <a href="{@docRoot}guide/components/activities.html#Lifecycle">gerenciar o ciclo de vida +da atividade</a> aplicam-se aos fragmentos. O que você também precisa entender, no entanto, é como a vida +da atividade afeta a vida do fragmento.</p> + +<p class="caution"><strong>Atenção:</strong> caso precise de um objeto {@link android.content.Context} +dentro do {@link android.app.Fragment}, é possível chamar {@link android.app.Fragment#getActivity()}. +No entanto, tome cuidado para chamar {@link android.app.Fragment#getActivity()} somente quando o fragmento +estiver anexado a uma atividade. Quando o fragmento ainda não estiver anexado, ou tiver sido desvinculado durante o fim +do seu ciclo de vida, {@link android.app.Fragment#getActivity()} retornará como nulo.</p> + + +<h3 id="CoordinatingWithActivity">Coordenação do ciclo de vida da atividade</h3> + +<p>O ciclo de vida da atividade em que o fragmento vive afeta diretamente o ciclo de vida +do fragmento, da mesma forma que um retorno de chamada de cada ciclo de vida da atividade resulta em um retorno de chamada semelhante +de cada fragmento. Por exemplo, quando a atividade receber {@link android.app.Activity#onPause}, +cada fragmento na atividade receberá {@link android.app.Fragment#onPause}.</p> + +<p>Os fragmentos têm alguns retornos de chamada do ciclo de vida extras. No entanto, isto trata da interação única +com a atividade para realizar ações como compilar e destruir a IU do fragmento. Esses +métodos adicionais de retorno de chamada são:</p> + +<dl> + <dt>{@link android.app.Fragment#onAttach onAttach()}</dt> + <dd>Chamado quando o fragmento tiver sido associado à atividade ({@link +android.app.Activity} é passado aqui).</dd> + <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt> + <dd>Chamado para criar a hierarquia de vistas associada ao fragmento.</dd> + <dt>{@link android.app.Fragment#onActivityCreated onActivityCreated()}</dt> + <dd>Chamado quando o método {@link android.app.Activity#onCreate +onCreate()} da atividade tiver retornado.</dd> + <dt>{@link android.app.Fragment#onDestroyView onDestroyView()}</dt> + <dd>Chamado quando a hierarquia de vistas associada ao fragmento estiver sendo removida.</dd> + <dt>{@link android.app.Fragment#onDetach onDetach()}</dt> + <dd>Chamado quando o fragmento estiver sendo desassociado da atividade.</dd> +</dl> + +<p>O fluxo do ciclo de vida do fragmento, afetado pela atividade do host, como ilustrado +pela figura 3. Nesta figura, é possível ver como cada estado sucessivo da atividade determina +qual método de retorno de chamada um fragmento pode receber. Por exemplo, quando a atividade recebe o retorno de chamada {@link +android.app.Activity#onCreate onCreate()}, um fragmento na atividade recebe nada mais +do que o retorno de chamada {@link android.app.Fragment#onActivityCreated onActivityCreated()}.</p> + +<p>Quando a atividade atinge o estado retomado, é possível adicionar e remover fragmentos +dela livremente. Portanto, somente quando a atividade estiver no estado retomado, o ciclo de vida +de um fragmento poderá alterar-se de forma independente.</p> + +<p>No entanto, quando a atividade deixa o estado retomado, o fragmento é novamente forçado +a passar pelo ciclo de vida pela atividade.</p> + + + + +<h2 id="Example">Exemplo</h2> + +<p>Para juntar tudo que foi discutido neste documento, abaixo há um exemplo de uma atividade +que usa dois fragmentos para criar um layout de dois painéis. A atividade abaixo inclui um fragmento +para exibir uma lista de títulos de peças de Shakespeare e outra para exibir um resumo da peça, +quando selecionada na lista. Ela também determina como fornecer diferentes configurações de fragmentos, +com base na configuração da tela.</p> + +<p class="note"><strong>Observação:</strong> O código fonte completo desta atividade está disponível em +<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code +FragmentLayout.java}</a>.</p> + +<p>A atividade principal aplica-se de maneira comum, durante {@link +android.app.Activity#onCreate onCreate()}:</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java main} + +<p>O layout aplicado é {@code fragment_layout.xml}:</p> + +{@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout} + +<p>Usando este layout, o sistema instancia {@code TitlesFragment} (que lista os títulos +das peças) assim que a atividade carrega o layout, enquanto que {@link android.widget.FrameLayout} +(onde o fragmento para exibir o resumo da peça aparecerá) consome o espaço do lado direito da tela, + mas primeiramente permanece vazio. Como verá abaixo, ele não estará visível até que o usuário selecione um item +na lista em que um fragmento esteja posicionado no {@link android.widget.FrameLayout}.</p> + +<p>No entanto, nem todas as configurações de tela são grandes o suficiente para exibir a lista +de peças e o resumo, lado a lado. Portanto, o layout acima é usado somente para configuração +de tela de paisagem, salvando-o em {@code res/layout-land/fragment_layout.xml}.</p> + +<p>Por isso, quando a tela está na orientação de retrato, o sistema aplica o seguinte layout, +que é salvo em {@code res/layout/fragment_layout.xml}:</p> + +{@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout} + +<p>Este layout inclui somente {@code TitlesFragment}. Isto significa que, quando o dispositivo +está na orientação de retrato, somente a lista de título das peças está disponível. Portanto, quando o usuário clicar +em um item da lista nesta configuração, o aplicativo iniciará uma nova atividade para exibir o resumo, +em vez de carregar um segundo fragmento.</p> + +<p>A seguir, é possível ver como isto é realizado com classes de fragmento. Primeiro, {@code +TitlesFragment}, que exibe a lista de peças de Shakespeare. Este fragmento estende {@link +android.app.ListFragment} e confia nele para lidar com grande parte do trabalho da vista de lista.</p> + +<p>Enquanto inspeciona este código, observe que há dois possíveis comportamentos quando um usuário +clica em um item de lista: dependendo de qual dos dois layouts está ativo, ele pode criar e exibir +um novo fragmento para exibir os detalhes na mesma atividade (adicionando o fragmento {@link +android.widget.FrameLayout}), ou iniciar uma nova atividade (onde o fragmento possa ser exibido).</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java titles} + +<p>O segundo fragmento, {@code DetailsFragment}, exibe o resumo da peça para o item selecionado +na lista de {@code TitlesFragment}:</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java details} + +<p>Uma nova chamada da classe {@code TitlesFragment}, ou seja, se o usuário clicar em um item de lista +e o layout original <em>não</em> incluir a vista {@code R.id.details} (a que +{@code DetailsFragment} pertence), o aplicativo iniciará a atividade {@code DetailsActivity} +para exibir o conteúdo do item.</p> + +<p>A seguir há {@code DetailsActivity}, que simplesmente embute {@code DetailsFragment} para exibir +o resumo da peça selecionada quando a tela está na orientação de retrato:</p> + +{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java +details_activity} + +<p>Observe que esta atividade finaliza-se se a configuração for de paisagem, +pois a atividade principal pode tomar o controle e exibir {@code DetailsFragment} juntamente com {@code TitlesFragment}. +Isto pode acontecer se o usuário iniciar {@code DetailsActivity} enquanto estiver na orientação de retrato, +mas alternar para orientação de paisagem (o que reinicia a atividade atual).</p> + + +<p>Para obter mais exemplos do uso de fragmentos (e arquivos fonte completos deste exemplo), +consulte o aplicativo de exemplo API Demos disponível em <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment"> +ApiDemos</a> (disponível para download em <a href="{@docRoot}resources/samples/get.html">Exemplos de componentes do SDK</a>).</p> + + diff --git a/docs/html-intl/intl/pt-br/guide/components/fundamentals.jd b/docs/html-intl/intl/pt-br/guide/components/fundamentals.jd new file mode 100644 index 000000000000..47b98458e642 --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/fundamentals.jd @@ -0,0 +1,480 @@ +page.title=Fundamentos de aplicativos +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>Neste documento</h2> +<ol> +<li><a href="#Components">Componentes de aplicativo</a> + <ol> + <li><a href="#ActivatingComponents">Ativação de componentes</a></li> + </ol> +</li> +<li><a href="#Manifest">O arquivo de manifesto</a> + <ol> + <li><a href="#DeclaringComponents">Declaração de componentes</a></li> + <li><a href="#DeclaringRequirements">Declaração de requisitos do aplicativo</a></li> + </ol> +</li> +<li><a href="#Resources">Recursos do aplicativo</a></li> +</ol> +</div> +</div> + +<p>Os aplicativos do Android são programados em linguagem de programação Java. As ferramentas Android SDK compilam +o código — em conjunto com todos os arquivos de dados e recursos — em um APK, que é o <i>pacote do Android</i>, +um arquivo de arquivamento com sufixo {@code .apk}. Os arquivos de APK contêm todo o conteúdo +de um aplicativo do Android e são os arquivos que os dispositivos desenvolvidos para Android usam para instalar o aplicativo.</p> + +<p>Depois de instalado em um dispositivo, cada aplicativo do Android é ativado em sua própria área de segurança: </p> + +<ul> + <li>O sistema operacional Android é um sistema Linux multiusuário em que cada aplicativo +é um usuário diferente.</li> + +<li>Por padrão, o sistema atribui a cada aplicativo um ID de usuário do Linux exclusivo (o ID é usado somente +pelo sistema e é desconhecido para o aplicativo). O sistema define permissões para todos os arquivos +em um aplicativo, de modo que somente o ID de usuário atribuído àquele aplicativo pode acessá-los. </li> + +<li>Cada processo tem sua própria máquina virtual (VM), portanto o código de um aplicativo é executado isoladamente +de outros aplicativos.</li> + +<li>Por padrão, cada aplicativo é executado em seu próprio processo Linux. O Android inicia o processo quando é preciso +executar algum componente do aplicativo; em seguida, encerra-o quando não mais é +necessário ou quando o sistema precisa recuperar memória para outros aplicativos.</li> +</ul> + +<p>Assim, o sistema Android implementa o <em>princípio do privilégio mínimo</em>. Ou seja, +cada aplicativo, por padrão, tem acesso somente aos componentes necessários para a execução do seu trabalho +e nada mais. Isso cria um ambiente muito seguro em que o aplicativo não pode acessar partes +do sistema para o qual não tem permissão.</p> + +<p>No entanto, sempre existe uma maneira de um aplicativo compartilhar dados com outros aplicativos +e acessar serviços do sistema:</p> + +<ul> + <li>É impossível fazer com que dois aplicativos compartilhem o mesmo ID de usuário do Linux, caso em que +eles são capazes de acessar os arquivos um do outro. Para preservar os recursos do sistema, os aplicativos com o mesmo +ID de usuário também podem ser combinados para serem executados no mesmo processo Linux e compartilhar a mesma VM +(também é preciso atribuir o mesmo certificado aos aplicativos).</li> + <li>Um aplicativo pode solicitar permissão para acessar dados de dispositivo como +contatos do usuário, mensagens SMS, o sistema montável (cartão SD), câmera, Bluetooth etc. Todas +as permissões de aplicativo devem ser concedidas pelo usuário no momento da instalação.</li> +</ul> + +<p>Essas são as informações básicas de como um aplicativo do Android existe dentro do sistema. O restante +deste documento apresenta o leitor a:</p> +<ul> + <li>Componentes fundamentais de estrutura que definem o aplicativo.</li> + <li>O arquivo de manifesto em que os componentes são declarados e os recursos de dispositivo necessários +ao aplicativo.</li> + <li>Recursos separados do código do aplicativo que permitem +otimizar o comportamento de uma variedade de configurações de dispositivo.</li> +</ul> + + + +<h2 id="Components">Componentes de aplicativo</h2> + +<p>Os componentes de aplicativo são os blocos de construção fundamentais de um aplicativo do Android. +Cada componente é um ponto diferente pelo qual o sistema pode entrar no aplicativo. Nem todos +os componentes são pontos de entrada reais para o usuário e alguns dependem uns dos outros, mas cada um existe +como uma entidade independente e desempenha uma função específica — cada um é um bloco de construção exclusivo +que ajuda a definir o comportamento geral do aplicativo.</p> + +<p>Há quatro tipos diferentes de componentes de aplicativo. Cada tipo tem uma finalidade distinta +e tem um ciclo de vida específico que define a forma pela qual o componente é criado e destruído.</p> + +<p>A seguir apresentam-se os quatro tipos de componentes de aplicativos:</p> + +<dl> + +<dt><b>Atividades</b></dt> + +<dd>As <i>atividades</i> representam uma tela única com uma interface do usuário. Por exemplo: +um aplicativo de e-mails pode ter uma atividade que mostra uma lista de novos +e-mails, outra atividade que compõe um e-mail e outra ainda que lê e-mails. Embora +essas atividades funcionem juntas para formar uma experiência de usuário coesa no aplicativo de e-mails, +elas são independentes entre si. Portanto, um aplicativo diferente pode iniciar qualquer uma +dessas atividades (se o aplicativo de e-mails permitir). Por exemplo: um aplicativo de câmera pode iniciar +a atividade no aplicativo de e-mail que compõe o novo e-mail para que o usuário compartilhe uma foto. + +<p>Uma atividade é implementada como uma subclasse de {@link android.app.Activity} — saiba mais sobre isso +no guia do desenvolvedor +<a href="{@docRoot}guide/components/activities.html">Atividades</a>.</p> +</dd> + + +<dt><b>Serviços</b></dt> + +<dd>Os <i>serviços</i> são componentes executados em segundo plano para realizar operações +de execução longa ou para realizar trabalho para processos remotos. Eles +não apresentam uma interface do usuário. Por exemplo: um serviço pode tocar música em segundo plano +enquanto o usuário está em um aplicativo diferente ou buscar dados na rede sem bloquear +a interação do usuário com uma atividade. Outro componente, como uma atividade, pode iniciar +o serviço e deixá-lo executar ou vincular-se a ele para interagir. + +<p>Um serviço é implementado como uma subclasse de {@link android.app.Service} — saiba mais sobre isso +no guia do desenvolvedor +<a href="{@docRoot}guide/components/services.html">Serviços</a>.</p> +</dd> + + +<dt><b>Provedores de conteúdo</b></dt> + +<dd>Os <i>provedores de conteúdo</i> gerenciam um conjunto compartilhado de dados do aplicativo. É possível armazenar os dados +no sistema de arquivos, em um banco de dados SQLite ou em qualquer local de armazenamento persistente +que o aplicativo possa acessar. Por meio do provedor de conteúdo, outros aplicativos podem consultar ou até modificar +os dados (se o provedor de conteúdo permitir). Por exemplo: o sistema Android oferece um provedor +de conteúdo que gerencia as informações de contato do usuário. Assim, qualquer aplicativo +com as permissões adequadas pode consultar parte do provedor de conteúdo (como {@link +android.provider.ContactsContract.Data}) para ler e gravar informações sobre uma pessoa específica. + +<p>Os provedores de conteúdo são úteis para ler e gravar dados privados +no aplicativo e não compartilhados. Por exemplo: o exemplo de aplicativo <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> usa +um provedor de conteúdo para salvar notas.</p> + +<p>Um provedor de conteúdo é implementado como uma subclasse de {@link android.content.ContentProvider} +e precisa implementar um conjunto padrão de APIs que permitem a outros aplicativos +realizar transações. Para obter mais informações, consulte o guia de desenvolvedor +<a href="{@docRoot}guide/topics/providers/content-providers.html">Provedores de conteúdo</a>.</p> +</dd> + + +<dt><b>Receptores de transmissão</b></dt> + +<dd>Os <i>receptores de transmissão</i> são componentes que respondem a anúncios de transmissão +por todo o sistema. Muitas transmissões se originam do sistema — por exemplo, uma transmissão que anuncia +que uma tela foi desligada, a bateria está baixa ou uma tela foi capturada. +Os aplicativos também podem iniciar transmissões — por exemplo, para comunicar a outros dispositivos +que alguns dados foram baixados no dispositivo e estão disponíveis para uso. Embora os receptores +de transmissão não exibam nenhuma interface do usuário, eles podem <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">criar uma notificação na barra de status</a> +para alertar ao usuário quando ocorre uma transmissão. Mais comumente, no entanto, um receptor de transmissão +é somente um "portal" para outros componentes e realiza uma quantidade mínima de trabalho. Por +exemplo: ele pode iniciar um serviço para executar um trabalho baseado no evento. + +<p>Os receptores de transmissão são implementados como subclasses de {@link android.content.BroadcastReceiver} +e cada transmissão é entregue como um objeto {@link android.content.Intent}. Para obter mais informações, +consulte a classe {@link android.content.BroadcastReceiver}.</p> +</dd> + +</dl> + + + +<p>Um aspecto exclusivo do projeto do sistema Android é que qualquer aplicativo pode iniciar +um componente de outro aplicativo. Por exemplo: se você quiser que o usuário capture +uma foto com a câmera do dispositivo, provavelmente haverá outro aplicativo que faz isso +e o seu aplicativo poderá usá-lo, ou seja, não será necessário desenvolver uma atividade para capturar uma foto. Não é +necessário incorporar nem mesmo vinculá-lo do aplicativo da câmera ao código. +Em vez disso, basta iniciar a atividade no aplicativo da câmera que captura +uma foto. Quando concluída, a foto até retorna ao aplicativo em questão para ser usada. Para o usuário, +parece que a câmera é realmente parte do aplicativo.</p> + +<p>Quando o sistema inicia um componente, ele inicia o processo daquele aplicativo (se ele já +não estiver em execução) e instancia as classes necessárias para o componente. Por exemplo: se o aplicativo +iniciar a atividade no aplicativo da câmera que captura uma foto, aquele aplicativo +é executado no processo que pertence ao aplicativo da câmera e não no processo do aplicativo. +Portanto, ao contrário dos aplicativos na maioria dos outros sistemas, os aplicativos do Android não têm um ponto +de entrada único (não há a função {@code main()}, por exemplo).</p> + +<p>Como o sistema executa cada aplicativo em um processo separado com permissões de arquivo +que restringem o acesso a outros aplicativos, o aplicativo não pode ativar diretamente um componente +a partir de outro aplicativo. No entanto, o sistema Android pode. Portanto, para ativar um componente +em outro aplicativo, é preciso enviar uma mensagem ao sistema que especifique a <em>intenção</em> +de iniciar um componente específico. Em seguida, o sistema ativa o componente.</p> + + +<h3 id="ActivatingComponents">Ativação de componentes</h3> + +<p>Três dos quatro tipos de componente — atividades, serviços +e receptores de transmissão — são ativados por uma mensagem assíncrona chamada <em>intenção</em>. +As intenções vinculam componentes individuais entre si em tempo de execução (como +mensageiros que solicitam uma ação de outros componentes), seja o componente pertencente +ao aplicativo ou não.</p> + +<p>A intenção é criada com um objeto {@link android.content.Intent}, que define uma mensagem +para ativar um componente específico ou um <em>tipo</em> específico de componente — as intenções +podem ser explícitas ou implícitas, respectivamente.</p> + +<p>Para atividades e serviços, as intenções definem a ação a executar (por exemplo, "exibir" ou +"enviar" algo) e podem especificar a URI dos dados usados na ação (entre outras coisas +que o componente a iniciar precisa saber). Por exemplo: uma intenção pode transmitir uma solicitação +de uma atividade para exibir uma imagem ou abrir uma página da web. Em alguns casos, é preciso iniciar +uma atividade para receber um resultado; nesse caso, a atividade também retorna +o resultado em um {@link android.content.Intent} (por exemplo, é possível emitir uma intenção para +que o usuário selecione um contato pessoal e o retorne a você — a intenção de retorno contém +uma URI que aponta para o contato selecionado).</p> + +<p>Para receptores de transmissão, a intenção simplesmente define +o anúncio que está sendo transmitido (por exemplo, uma transmissão para indicar que a bateria do dispositivo está acabando +contém uma string de ação conhecida que indica "nível baixo da bateria").</p> + +<p>O outro tipo de componente, o provedor de conteúdo, não é ativado por intenções. Em vez disso, +ele é ativado por uma solicitação de um {@link android.content.ContentResolver}. O resolvedor +de conteúdo manipula todas as transações diretas com o provedor de conteúdo para que o componente +que executa as transações com o provedor não precise e, em vez disso, chama os métodos no objeto {@link +android.content.ContentResolver}. Isso deixa uma camada de abstração entre o provedor +de conteúdo e o componente que solicita informações (por segurança).</p> + +<p>Há dois métodos separados para ativar cada tipo de componente:</p> +<ul> + <li>É possível iniciar uma atividade (ou dar-lhe algo novo para fazer) +passando uma {@link android.content.Intent} a {@link android.content.Context#startActivity +startActivity()} ou {@link android.app.Activity#startActivityForResult startActivityForResult()} +(para que, quando desejado, a atividade retorne um resultado).</li> + <li>É possível iniciar um dispositivo (ou dar novas instruções a um serviço em andamento) +passando uma {@link android.content.Intent} a {@link android.content.Context#startService +startService()}. Ou então, é possível vincular ao serviço passando uma{@link android.content.Intent} +a {@link android.content.Context#bindService bindService()}.</li> + <li>É possível iniciar uma transmissão passando uma{@link android.content.Intent} a métodos como +{@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}, {@link +android.content.Context#sendOrderedBroadcast(Intent, String) sendOrderedBroadcast()} ou {@link +android.content.Context#sendStickyBroadcast sendStickyBroadcast()}.</li> + <li>É possível iniciar uma consulta a um provedor de conteúdo chamando {@link +android.content.ContentProvider#query query()} em um {@link android.content.ContentResolver}.</li> +</ul> + +<p>Para obter mais informações sobre intenções, consulte o documento +<a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de intenções</a>. Veja mais informações sobre a ativação de componentes específicos +nos seguintes documentos: <a href="{@docRoot}guide/components/activities.html">Atividades</a>, <a href="{@docRoot}guide/components/services.html">Serviços</a>, {@link +android.content.BroadcastReceiver} e <a href="{@docRoot}guide/topics/providers/content-providers.html">Provedores de conteúdo</a>.</p> + + +<h2 id="Manifest">O arquivo de manifesto</h2> + +<p>Antes de o sistema Android iniciar um componente de aplicativo, é preciso ler o arquivo {@code AndroidManifest.xml} +(o arquivo de "manifesto") +do aplicativo para que o sistema saiba se o componente existe. O aplicativo precisa declarar todos os seus componentes nesse arquivo, que deve estar na raiz +do diretório do projeto do aplicativo.</p> + +<p>O manifesto faz outras coisas além de declarar os componentes do aplicativo, +por exemplo:</p> +<ul> + <li>Identifica todas as permissões do usuário de que o aplicativo precisa, como acesso à internet +ou acesso de somente leitura aos contatos do usuário.</li> + <li>Declara o <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">nível de API</a> mínimo +exigido pelo aplicativo com base nas APIs que o aplicativo usa.</li> + <li>Declara os recursos de hardware e software usados ou exigidos pelo aplicativo, como câmera, +serviços de bluetooth ou tela multitoque.</li> + <li>As bibliotecas de API às quais o aplicativo precisa vincular-se (outras além das APIs +de estrutura do Android), como a <a href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">biblioteca +Google Maps</a>.</li> + <li>E outros.</li> +</ul> + + +<h3 id="DeclaringComponents">Declaração de componentes</h3> + +<p>A principal tarefa do manifesto é informar ao sistema os componentes do aplicativo. Por +exemplo: um arquivo de manifesto pode declarar uma atividade da seguinte forma: </p> + +<pre> +<?xml version="1.0" encoding="utf-8"?> +<manifest ... > + <application android:icon="@drawable/app_icon.png" ... > + <activity android:name="com.example.project.ExampleActivity" + android:label="@string/example_label" ... > + </activity> + ... + </application> +</manifest></pre> + +<p>No elemento <code><a +href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code> +, o atributo {@code android:icon} aponta para recursos de um ícone que identifica +o aplicativo.</p> + +<p>No elemento <code><a +href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>, +o atributo {@code android:name} especifica o nome da classe totalmente qualificada da subclasse de {@link +android.app.Activity} e o atributo {@code android:label} especifica uma string +a usar como a etiqueta da atividade visível ao usuário.</p> + +<p>É preciso declarar todos os componentes desta forma:</p> +<ul> + <li>Elementos <code><a +href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +para atividades</li> + <li>Elementos <code><a +href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> +para serviços</li> + <li>Elementos <code><a +href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code> +para receptores de transmissão</li> + <li>Elementos <code><a +href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> +para provedores de conteúdo</li> +</ul> + +<p>Atividades, serviços e provedores de conteúdo incluídos na fonte, mas não declarados +no manifesto, não ficam visíveis para o sistema e, consequentemente, podem não ser executados. No entanto, receptores +de transmissão +podem ser declarados no manifesto dinamicamente no código (como objetos +{@link android.content.BroadcastReceiver}) e registrados no sistema chamando-se +{@link android.content.Context#registerReceiver registerReceiver()}.</p> + +<p>Para obter mais informações sobre a estrutura do arquivo de manifesto de aplicativos, consulte a documentação +<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">O arquivo AndroidManifest.xml</a>. </p> + + + +<h3 id="DeclaringComponentCapabilities">Declaração de recursos de componentes</h3> + +<p>Conforme abordado acima, em <a href="#ActivatingComponents">Ativação de componentes</a>, é possível usar +uma {@link android.content.Intent} para iniciar atividades, serviços e receptores de transmissão. Isso pode ser feito +nomeando-se explicitamente o componente-alvo (usando o nome da classe do componente) na intenção. No entanto, +a verdadeira força das intenções reside no conceito de <em>intenções implícitas</em>. As intenções implícitas +descrevem simplesmente o tipo de ação a executar (e, opcionalmente, os dados em que +a ação deve ser executada) e permitem ao sistema encontrar e iniciar um componente no dispositivo que pode executar +a ação. Se houver mais de um componente que possa executar a ação descrita +pela intenção, o usuário selecionará qual deles usar.</p> + +<p>Para o sistema identificar os componentes que podem responder a uma intenção, compara-se +a intenção recebida com os <i>filtros de intenções</i> fornecidos no arquivo de manifesto de outros aplicativos +do dispositivo.</p> + +<p>Ao declarar uma atividade no manifesto do aplicativo, pode-se incluir +filtros de intenções que declarem os recursos da atividade para que ela responda +a intenções de outros aplicativos. Para declarar um filtro de intenções no componentes, +adiciona-se um elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code +<intent-filter>}</a> como filho do elemento de declaração do componente.</p> + +<p>Por exemplo: se você estiver programando um aplicativo de e-mail com uma atividade de compor um novo e-mail, +é possível declarar um filtro de intenções para responder a intenções "enviar" (para enviar um novo e-mail), assim:</p> +<pre> +<manifest ... > + ... + <application ... > + <activity android:name="com.example.project.ComposeEmailActivity"> + <intent-filter> + <action android:name="android.intent.action.SEND" /> + <data android:type="*/*" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + </application> +</manifest> +</pre> + +<p>Em seguida, se outro aplicativo criar uma intenção com a ação {@link +android.content.Intent#ACTION_SEND} e passá-la para {@link android.app.Activity#startActivity +startActivity()}, o sistema poderá iniciar a atividade de forma que o usuário possa rascunhar e enviar +um e-mail.</p> + +<p>Para obter mais informações sobre filtros de intenções, consulte o documento <a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de intenções</a>. +</p> + + + +<h3 id="DeclaringRequirements">Declaração de requisitos do aplicativo</h3> + +<p>Existem vários dispositivos desenvolvidos para Android e nem todos apresentam os mesmos +recursos e características. Para evitar que o aplicativo seja instalado em dispositivos +que não contenham os recursos que o aplicativo necessita, é importante definir um perfil +para os tipos de dispositivo compatíveis com o aplicativo. É preciso declarar os requisitos de dispositivo e software +no arquivo de manifesto. A maior parte dessas declarações é somente informativa e o sistema não as lê, +mas serviços externos, como o Google Play, as leem para oferecer uma filtragem +aos usuários quando buscam esses aplicativos para seu dispositivo.</p> + +<p>Por exemplo: se o aplicativo exige uma câmera e usa APIs introduzidas no Android 2.1 (<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API de nível</a> 7), +deve-se declarar esses requisitos no arquivo de manifesto da seguinte forma:</p> + +<pre> +<manifest ... > + <uses-feature android:name="android.hardware.camera.any" + android:required="true" /> + <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" /> + ... +</manifest> +</pre> + +<p>Assim, dispositivos que <em>não</em> tenham câmera e tenham +versão Android <em>anterior</em> a 2.1 não poderão instalar o aplicativo a partir do Google Play.</p> + +<p>No entanto, também é possível declarar que o aplicativo usa a câmera como recurso +<em>não obrigatório</em>. Nesse caso, o aplicativo precisa definir o atributo <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#required">{@code required}</a> + como {@code "false"} e verificar em tempo de execução +se o dispositivo tem câmera e desativar os recursos da câmera conforme o necessário.</p> + +<p>Veja mais informações sobre o gerenciamento da compatibilidade do aplicativo com diferentes dispositivos +no documento <a href="{@docRoot}guide/practices/compatibility.html">Compatibilidade +do dispositivo</a>.</p> + + + +<h2 id="Resources">Recursos do aplicativo</h2> + +<p>Os aplicativos Android são compostos por mais do que somente códigos — eles requerem recursos +separados do código-fonte, como imagens, arquivos de áudio e tudo o que se relaciona +com a apresentação visual do aplicativo. Por exemplo: deve-se definir animações, menus, estilos, cores +e o layout das interfaces do usuário da atividade com arquivos XML. O uso de recursos de aplicativo facilita +a atualização de diversas características do aplicativo sem a necessidade de modificar +o código e — fornecendo conjuntos de recursos alternativos — permite otimizar o aplicativo +para diversas configurações de dispositivo (como idiomas e tamanhos de tela diferentes).</p> + +<p>Para todo recurso incluído no projeto Android, as ferramentas de programação SDK definem +um ID inteiro exclusivo que o programador pode usar para referenciar o recurso do código do aplicativo +ou de outros recursos definidos no XML. Por exemplo: se o aplicativo contiver um arquivo de imagem de nome {@code +logo.png} (salvo no diretório {@code res/drawable/}), as ferramentas de SDK gerarão um ID de recurso +chamado {@code R.drawable.logo}, que pode ser usado para referenciar a imagem e inseri-la +na interface do usuário.</p> + +<p>Um dos aspectos mais importantes de fornecer recursos separados do código-fonte +é a capacidade de fornecer recursos alternativos para diferentes configurações +de dispositivo. Por exemplo: ao definir strings de IU em XML, é possível converter as strings em outros +idiomas e salvá-las em arquivos separados. Em seguida, com base em um <em>qualificador</em> de idioma +acrescentado ao nome do diretório do recurso (como {@code res/values-fr/} para valores +de string em francês) e a configuração de idioma do usuário, o sistema Android aplica as strings de idioma adequadas +à IU.</p> + +<p>O Android aceita vários <em>qualificadores</em> para recursos alternativos. O qualificador +é uma string curta incluída no nome dos diretórios de recurso para definir +a configuração de dispositivo em que esses recursos serão usados. Outro exemplo: +deve-se criar diferentes layouts para as atividades conforme a orientação +e o tamanho da tela do dispositivo. Por exemplo: quando a tela do dispositivo está em orientação +retrato (vertical), pode ser desejável um layout com botões na vertical, mas, quando a tela está em orientação +paisagem (horizontal), os botões devem estar alinhados horizontalmente. Para alterar o layout +conforme a orientação, pode-se definir dois layouts diferentes e aplicar o qualificador +adequado ao nome do diretório de cada layout. Em seguida, o sistema aplica automaticamente o layout adequado +conforme a orientação atual do dispositivo.</p> + +<p>Para obter mais informações sobre os diferentes tipos de recursos a incluir no aplicativo +e como criar recursos alternativos para diferentes configurações de dispositivo, leia <a href="{@docRoot}guide/topics/resources/providing-resources.html">Como fornecer recursos</a>.</p> + + + +<div class="next-docs"> +<div class="col-6"> + <h2 class="norule">Continue lendo sobre:</h2> + <dl> + <dt><a href="{@docRoot}guide/components/intents-filters.html">Intenções e filtros de intenções</a> + </dt> + <dd>Informações sobre o uso de APIs {@link android.content.Intent} para +ativar componentes de aplicativos, como atividades e serviços, e como disponibilizar componentes +de aplicativo para uso em outros aplicativos.</dd> + <dt><a href="{@docRoot}guide/components/activities.html">Atividades</a></dt> + <dd>Informações sobre a criação de uma instância da classe {@link android.app.Activity}, +que permite uma tela diferente no aplicativo com uma interface do usuário.</dd> + <dt><a href="{@docRoot}guide/topics/resources/providing-resources.html">Como fornecer recursos</a></dt> + <dd>Informações sobre a estrutura de aplicativos Android para recursos de aplicativo separados do código-fonte +, inclusive como fornecer recursos alternativos para configurações +de dispositivo específicas. + </dd> + </dl> +</div> +<div class="col-6"> + <h2 class="norule">Você também pode se interessar por:</h2> + <dl> + <dt><a href="{@docRoot}guide/practices/compatibility.html">Compatibilidade do dispositivo</a></dt> + <dd>Informações sobre como o Android funciona em diferentes tipos de dispositivo e uma introdução +a como otimizar o aplicativo para cada dispositivo ou restringir a disponibilidade +a diferentes dispositivos.</dd> + <dt><a href="{@docRoot}guide/topics/security/permissions.html">Permissões do sistema</a></dt> + <dd>Informações sobre como o aplicativo restringe o acesso do Android a determinadas APIs sem um +sistema de permissão que exija o consentimento do usuário para que o aplicativo use essas APIs.</dd> + </dl> +</div> +</div> + diff --git a/docs/html-intl/intl/pt-br/guide/components/index.jd b/docs/html-intl/intl/pt-br/guide/components/index.jd new file mode 100644 index 000000000000..02fcaa63c63a --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/index.jd @@ -0,0 +1,57 @@ +page.title=Componentes do aplicativo +page.landing=true +page.landing.intro=A estrutura de aplicativo do Android permite criar aplicativos ricos e inovadores usando um conjunto de componentes reutilizáveis. Esta seção explica como criar os componentes que definem os blocos de construção do aplicativo e como conectá-los usando intenções. +page.metaDescription=A estrutura de aplicativo do Android permite criar aplicativos ricos e inovadores usando um conjunto de componentes reutilizáveis. Esta seção mostra como criar os componentes que definem os blocos de construção do aplicativo e como conectá-los usando intenções. +page.landing.image=images/develop/app_components.png +page.image=images/develop/app_components.png + +@jd:body + +<div class="landing-docs"> + + <div class="col-6"> + <h3>Artigos de blogue</h3> + + <a href="http://android-developers.blogspot.com/2012/05/using-dialogfragments.html"> + <h4>Uso de DialogFragments</h4> + <p>Nesta publicação, mostrarei como usar DialogFragments com a biblioteca de suporte v4 (para compatibilidade retroativa em dispositivos anteriores a Honeycomb) para mostrar uma caixa de diálogo de edição simples e retornar um resultado para a Atividade chamadora usando uma interface.</p> + </a> + + <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html"> + <h4>Fragmentos para todos</h4> + <p>Hoje, lançamos uma biblioteca estática que expõe a mesma API Fragments (bem como o novo LoaderManager e algumas outras classes) para que aplicativos compatíveis com Android 1.6 e posteriores possam usar fragmentos para criar interfaces de usuário compatíveis com tablets. </p> + </a> + + <a href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html"> + <h4>Multiencadeamento para desempenho</h4> + <p>Uma boa prática para criar aplicativos responsivos é garantir que o encadeamento principal da IU +realize uma quantidade mínima de trabalho. Qualquer tarefa possivelmente longa que possa travar o aplicativo deve ser tratada +em um encadeamento diferente.</p> + </a> + </div> + + <div class="col-6"> + <h3>Treinamento</h3> + + <a href="http://developer.android.com/training/basics/activity-lifecycle/index.html"> + <h4>Gerenciamento do ciclo de vida da atividade</h4> + <p>Essa lição explica a importância dos métodos de retorno de chamada do ciclo de vida que cada instância de +Atividade recebe e como utilizá-los para que a atividade faça o que o usuário espera e não consuma recursos +do sistema quando não estiver em uso.</p> + </a> + + <a href="http://developer.android.com/training/basics/fragments/index.html"> + <h4>Como construir uma IU dinâmica com Fragmentos</h4> + <p>Esta classe mostra como criar uma experiência dinâmica para o usuário com fragmentos e como otimizar +a experiência do aplicativo ao usuário para dispositivos com diferentes tamanhos de tela e ainda manter compatibilidade com dispositivos que executem versões +de plataforma tão antigas quanto o Android 1.6.</p> + </a> + + <a href="http://developer.android.com/training/sharing/index.html"> + <h4>Compartilhamento de conteúdo</h4> + <p>Esta classe aborda algumas formas comuns para enviar e receber conteúdo entre +aplicativos usando APIs de Intenção e o objeto ActionProvider.</p> + </a> + </div> + +</div> diff --git a/docs/html-intl/intl/pt-br/guide/components/intents-filters.jd b/docs/html-intl/intl/pt-br/guide/components/intents-filters.jd new file mode 100644 index 000000000000..75bc5085229a --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/intents-filters.jd @@ -0,0 +1,901 @@ +page.title=Intenções e filtros de intenções +page.tags="IntentFilter" +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>Neste documento</h2> +<ol> + <li><a href="#Types">Tipos de intenções</a></li> + <li><a href="#Building">Criação de uma intenção</a> + <ol> + <li><a href="#ExampleExplicit">Exemplo de intenção explícita</a></li> + <li><a href="#ExampleSend">Exemplo de intenção implícita</a></li> + <li><a href="#ForceChooser">Forçar um seletor de aplicativo</a></li> + </ol> + </li> + <li><a href="#Receiving">Recepção de uma intenção implícita</a> + <ol> + <li><a href="#ExampleFilters">Exemplos de filtros</a></li> + </ol> + </li> + <li><a href="#PendingIntent">Uso de uma intenção pendente</a></li> + <li><a href="#Resolution">Resolução de intenções</a> + <ol> + <li><a href="#ActionTest">Teste de ação</a></li> + <li><a href="#CategoryTest">Teste de categoria</a></li> + <li><a href="#DataTest">Teste de dados</a></li> + <li><a href="#imatch">Correspondência de intenções</a></li> + </ol> + </li> +</ol> + +<h2>Veja também</h2> +<ol> +<li><a href="{@docRoot}training/basics/intents/index.html">Interação com outros aplicativos</a></li> +<li><a href="{@docRoot}training/sharing/index.html">Compartilhamento de conteúdo</a></li> +</ol> + +</div> +</div> + + + + +<p>A {@link android.content.Intent} é um objeto de mensagem que pode ser usado para solicitar uma ação +de outro <a href="{@docRoot}guide/components/fundamentals.html#Components">componente de aplicativo</a>. +Embora as intenções facilitem a comunicação entre componentes de diversos modos, há três +casos de uso fundamentais:</p> + +<ul> +<li><b>Para iniciar uma atividade:</b> +<p>A {@link android.app.Activity} representa uma única tela em um aplicativo. É possível iniciar uma nova +instância de uma {@link android.app.Activity} passando uma {@link android.content.Intent} +a {@link android.content.Context#startActivity startActivity()}. A {@link android.content.Intent} +descreve a atividade a iniciar e carrega todos os dados necessários.</p> + +<p>Se você deseja receber um resultado da atividade quando ela finalizar, +chame {@link android.app.Activity#startActivityForResult +startActivityForResult()}. Sua atividade recebe o resultado +como um objeto {@link android.content.Intent} separado no retorno de chamada de {@link +android.app.Activity#onActivityResult onActivityResult()} da atividade. +Para obter mais informações, consulte o guia <a href="{@docRoot}guide/components/activities.html">Atividades</a>.</p></li> + +<li><b>Para iniciar um serviço:</b> +<p>O {@link android.app.Service} é um componente que realiza operações em segundo plano +sem interface de usuário. É possível iniciar um serviço para realizar uma operação que acontece uma vez +(como baixar um arquivo) passando uma {@link android.content.Intent} +a {@link android.content.Context#startService startService()}. A {@link android.content.Intent} +descreve o serviço a iniciar e carrega todos os dados necessários.</p> + +<p>Se o serviço for projetado com uma interface servidor-cliente, é possível vincular ao serviço +a partir de outro componente passando uma {@link android.content.Intent} a {@link +android.content.Context#bindService bindService()}</code>. Para obter mais informações, consulte o guia <a href="{@docRoot}guide/components/services.html">Serviços</a>.</p></li> + +<li><b>Para fornecer uma transmissão:</b> +<p>Transmissão é uma mensagem que qualquer aplicativo pode receber. O sistema fornece diversas +transmissões para eventos do sistema, como quando o sistema inicializa ou o dispositivo inicia o carregamento. +Você pode fornecer uma transmissão a outros aplicativos passando uma {@link android.content.Intent} +a {@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}, +{@link android.content.Context#sendOrderedBroadcast(Intent, String) +sendOrderedBroadcast()} ou {@link +android.content.Context#sendStickyBroadcast sendStickyBroadcast()}.</p> +</li> +</ul> + + + + +<h2 id="Types">Tipos de intenções</h2> + +<p>Há dois tipos de intenções:</p> + +<ul> +<li>As <b>intenções explícitas</b> especificam o componente a iniciar pelo nome +(o nome de classe totalmente qualificado). Normalmente, usa-se uma intenção explícita para iniciar um componente +no próprio aplicativo porque se sabe o nome de classe da atividade ou serviço que se deseja iniciar. +Por exemplo, iniciar uma nova atividade em resposta a uma ação do usuário ou iniciar um serviço para baixar +um arquivo em segundo plano.</li> + +<li>As <b>intenções implícitas</b> não nomeiam nenhum componente específico, mas declaram uma ação geral +a realizar, o que permite que um componente de outro aplicativo a trate. Por exemplo: se você deseja +exibir ao usuário uma localização em um mapa, pode usar uma intenção implícita para solicitar que outro aplicativo +capaz exiba uma localização especificada no mapa.</li> +</ul> + +<p>Ao criar uma intenção explícita para iniciar uma atividade ou serviço, o sistema inicia imediatamente +o componente do aplicativo especificado no objeto {@link android.content.Intent} .</p> + +<div class="figure" style="width:446px"> +<img src="{@docRoot}images/components/intent-filters@2x.png" width="446" alt="" /> +<p class="img-caption"><strong>Figura 1.</strong> Ilustração de como uma intenção implícita +é fornecida pelo sistema para iniciar outra atividade: <b>[1]</b> <em>A atividade A</em> cria uma +{@link android.content.Intent} com uma descrição de ação e passa-a para {@link +android.content.Context#startActivity startActivity()}. <b>[2]</b> O sistema Android busca, em todos +os aplicativos, um filtro de intenções que corresponda à intenção. Ao encontrar uma correspondência, <b>[3]</b> o sistema +inicia a atividade correspondente (<em>atividade B</em>) chamando seu método {@link +android.app.Activity#onCreate onCreate()} e passando a {@link android.content.Intent} para ele. +</p> +</div> + +<p>Ao criar uma intenção implícita, o sistema Android encontra o componente adequado para iniciar, +comparando o conteúdo da intenção aos <em>filtros de intenções</em> declarados no <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">arquivo de manifesto</a> de outros aplicativos +no dispositivo. Se a intenção corresponder a um filtro de intenções, o sistema iniciará esse componente e entregará +o objeto {@link android.content.Intent}. Se diversos filtros de intenções corresponderem, o sistema +exibirá uma caixa de diálogo para que o usuário selecione o aplicativo que deseja usar.</p> + +<p>O filtro de intenções é uma expressão em um arquivo de manifesto do aplicativo +que especifica o tipo de intenções que o componente +gostaria de receber. Por exemplo, ao declarar um filtro de intenções para uma atividade, +outros aplicativos se tornam capazes de iniciar diretamente sua atividade com o determinado tipo de intenção. +Do mesmo modo, se você <em>não</em> declarar nenhum filtro de intenções para uma atividade, ela poderá ser iniciada +somente com uma intenção explícita.</p> + +<p class="caution"><strong>Atenção:</strong> para garantir a segurança do seu aplicativo, sempre use uma intenção +explícita ao iniciar um {@link android.app.Service} e não +declare filtros de intenções para os serviços. O uso de uma intenção implícita para iniciar um serviço representa +um risco de segurança porque não é possível determinar qual serviço responderá à intenção +e o usuário não poderá ver que serviço é iniciado. A partir do Android 5.0 (API de nível 21), o sistema +lança uma exceção ao chamar {@link android.content.Context#bindService bindService()} +com uma intenção implícita.</p> + + + + + +<h2 id="Building">Criação de uma intenção</h2> + +<p>Um objeto {@link android.content.Intent} carrega informações que o sistema Android usa +para determinar o componente a iniciar (como o nome exato do componente ou categoria +do componente que deve receber a intenção), além de informações que o componente receptor usa para +realizar a ação adequadamente (como a ação a tomar e os dados a usar).</p> + + +<p>As informações principais contidas em uma {@link android.content.Intent} são as seguintes:</p> + +<dl> + +<dt><b>Nome do componente</b></dt> +<dd>O nome do componente a iniciar. + +<p>É opcional, mas é a informação fundamental que torna uma intenção +<b>explícita</b>, o que significa que a intenção deve ser entregue somente ao componente do aplicativo +definido pelo nome do componente. Sem nome de componente, a intenção será <b>implícita</b> +e o sistema decidirá qual componente deve receber a intenção, com base nas informações de outra intenção +(como a ação, os dados e a categoria — descritos abaixo). Portanto, se for necessário iniciar +um componente específico no seu aplicativo, deve-se especificar o nome do componente.</p> + +<p class="note"><strong>Observação:</strong> ao iniciar um {@link android.app.Service}, deve-se +<strong>sempre especificar o nome do componente</strong>. Caso contrário, não será possível determinar qual serviço +responderá à intenção e o usuário não poderá ver que serviço é iniciado.</p> + +<p>Esse campo da {@link android.content.Intent} é um +objeto {@link android.content.ComponentName} que pode ser especificado usando um nome +de classe totalmente qualificado do componente-alvo, inclusive o nome do pacote do aplicativo. Por exemplo, +{@code com.example.ExampleActivity}. É possível definir o nome do componente com {@link +android.content.Intent#setComponent setComponent()}, {@link android.content.Intent#setClass +setClass()}, {@link android.content.Intent#setClassName(String, String) setClassName()} ou com +o construtor de {@link android.content.Intent}.</p> + +</dd> + +<p><dt><b>Ação</b></dt> +<dd>String que especifica a ação genérica a realizar (como <em>exibir</em> ou <em>selecionar</em>). + +<p>No caso de uma intenção de transmissão, essa é a ação que entrou em vigor e que está sendo relatada. +A ação determina amplamente como o resto da intenção é estruturado — especificamente, +o que está contido nos dados e em extras. + +<p>É possível especificar as ações para uso por intenções dentro do aplicativo (ou para uso por outros +aplicativos para chamar componentes no seu aplicativo), mas normalmente usam-se constantes de ação +definidas pela classe {@link android.content.Intent} ou por outras classes de estrutura. A seguir há algumas +ações comuns para iniciar uma atividade:</p> + +<dl> +<dt>{@link android.content.Intent#ACTION_VIEW}</dt> + <dd>Use essa ação em uma intenção com {@link + android.content.Context#startActivity startActivity()} quando houver informações que + uma atividade possa exibir ao usuário, como uma foto para exibição em um aplicativo de galeria ou um endereço + para exibição em um aplicativo de mapa.</dd> + +<dt>{@link android.content.Intent#ACTION_SEND}</dt> + <dd>Também conhecida como a intenção de "compartilhamento", ela deve ser usada em uma intenção com {@link + android.content.Context#startActivity startActivity()} quando houver alguns dados que o usuário possa + compartilhar por meio de outro aplicativo, como um aplicativo de e-mail ou de compartilhamento social.</dd> +</dl> + +<p>Consulte a referência da classe {@link android.content.Intent} para obter mais +constantes que definem ações genéricas. Outras ações são definidas +em outros locais na estrutura do Android, como nas {@link android.provider.Settings} para ações +que abrem telas específicas no aplicativo de Configurações do sistema.</p> + +<p>É possível especificar a ação para uma intenção com {@link android.content.Intent#setAction +setAction()} ou com um construtor de {@link android.content.Intent}.</p> + +<p>Se você definir as próprias ações, certifique-se de incluir o nome do pacote do seu aplicativo +como prefixo. Por exemplo:</p> +<pre>static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";</pre> +</dd> + +<dt><b>Dados</b></dt> +<dd>A URI (um objeto {@link android.net.Uri}) que referencia os dados a serem aproveitados e/ou o +tipo MIME desses dados. O tipo dos dados fornecidos geralmente é determinado pela ação da intenção. +Por exemplo: se a ação for {@link android.content.Intent#ACTION_EDIT}, os dados devem conter +a URI do documento a editar. + +<p>Ao criar uma intenção, +em geral, é importante especificar o tipo de dados (seu tipo MIME) em adição à URI. +Por exemplo: uma atividade capaz de exibir imagens provavelmente não será capaz +de reproduzir um arquivo de áudio, mesmo que os formatos da URI sejam similares. +Portanto, especificar o tipo MIME dos dados ajuda o sistema +Android a encontrar o melhor componente para receber a intenção. +Contudo, o tipo MIME, às vezes, pode ser inferido a partir da URI — especificamente quando os dados são +uma URI de {@code content:}, indicando que os dados se localizam no dispositivo e são controlados +por um {@link android.content.ContentProvider}, que torna o tipo MIME dos dados visíveis para o sistema.</p> + +<p>Para definir somente a URI de dados, chame {@link android.content.Intent#setData setData()}. +Para definir somente o tipo MIME, chame {@link android.content.Intent#setType setType()}. Se necessário, +é possível definir ambos explicitamente com {@link +android.content.Intent#setDataAndType setDataAndType()}.</p> + +<p class="caution"><strong>Atenção:</strong> se você deseja definir a URI e o tipo MIME, +<strong>não</strong> chame {@link android.content.Intent#setData setData()} +e {@link android.content.Intent#setType setType()}, pois eles anulam seus valores mutuamente. +Sempre use {@link android.content.Intent#setDataAndType setDataAndType()} para definir +a URI e o tipo MIME juntos.</p> +</dd> + +<p><dt><b>Categoria</b></dt> +<dd>String que contém informações adicionais sobre o tipo de componente +que deve tratar da intenção. Qualquer número de descrições de categoria pode ser +inserido em uma intenção, mas a maioria das intenções não requer nenhuma categoria. +A seguir há algumas categorias comuns: + +<dl> +<dt>{@link android.content.Intent#CATEGORY_BROWSABLE}</dt> + <dd>A atividade-alvo permite seu início por um navegador da web para exibir dados + referenciados por um link — como uma imagem ou uma mensagem de e-mail. + </dd> +<dt>{@link android.content.Intent#CATEGORY_LAUNCHER}</dt> + <dd>A atividade é a atividade inicial de uma tarefa e é listada + no inicializador do aplicativo do sistema. + </dd> +</dl> + +<p>Consulte a descrição da classe {@link android.content.Intent} para obter a lista completa +de categorias.</p> + +<p>É possível especificar uma categoria com {@link android.content.Intent#addCategory addCategory()}.</p> +</dd> +</dl> + + +<p>As propriedades listadas abaixo (nome do componente, ação, dados e categoria) representam +as características de definição de uma intenção. Ao ler estas propriedades, o sistema Android +será capaz de definir o componente de aplicativo que ele deve iniciar.</p> + +<p>Contudo, uma intenção pode carregar informações adicionais que não afetam +o modo com que é tratada para um componente do aplicativo. As intenções também podem fornecer:</p> + +<dl> +<dt><b>Extras</b></dt> +<dd>Pares de valores-chave que carregam informações adicionais exigidas para realizar a ação solicitada. +Assim, como algumas ações usam determinados tipos de URIs de dados, outras também usam determinados extras. + +<p>É possível adicionar dados extras com diversos métodos {@link android.content.Intent#putExtra putExtra()}, +cada um aceitando dois parâmetros: o nome principal e o valor. +Também é possível criar um objeto {@link android.os.Bundle} com todos os dados extras e, em seguida, inserir +o {@link android.os.Bundle} na {@link android.content.Intent} com {@link +android.content.Intent#putExtras putExtras()}.</p> + +<p>Por exemplo: ao criar uma intenção para enviar um e-mail com +{@link android.content.Intent#ACTION_SEND}, é possível especificar o recipiente "para" com +a chave {@link android.content.Intent#EXTRA_EMAIL} e especificar o "assunto" com +a chave {@link android.content.Intent#EXTRA_SUBJECT}.</p> + +<p>A classe {@link android.content.Intent} especifica diversas constantes {@code EXTRA_*} +para tipos de dados padronizados. Se for necessário declarar chaves extras (para intenções que +seu aplicativo receba), certifique-se de incluir o nome do pacote do aplicativo +como prefixo. Por exemplo:</p> +<pre>static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";</pre> +</dd> + +<dt><b>Sinalizadores</b></dt> +<dd>Sinalizadores definidos na classe {@link android.content.Intent} que funcionam como metadados +para a intenção. Os sinalizadores podem instruir o sistema Android sobre como inicializar uma atividade (por exemplo, a qual +<a href="{@docRoot}guide/components/tasks-and-back-stack.html">tarefa</a> a atividade deve +pertencer) e como tratá-la após sua inicialização (por exemplo, se ela pertencer a uma lista de atividades +recentes). + +<p>Para obter mais informações, consulte o método {@link android.content.Intent#setFlags setFlags()}.</p> +</dd> + +</dl> + + + + +<h3 id="ExampleExplicit">Exemplo de intenção explícita</h3> + +<p>A intenção explícita é usada para inicializar um componente específico de um aplicativo, como +uma atividade ou serviço em particular, no seu aplicativo. Para criar uma intenção explícita, defina +o nome do componente para o objeto {@link android.content.Intent} — todas +as outras propriedades da intenção são opcionais.</p> + +<p>Por exemplo: se você criar um serviço no aplicativo, chamado {@code DownloadService} e +projetado para baixar um arquivo da web, poderá iniciá-lo com o código a seguir:</p> + +<pre> +// Executed in an Activity, so 'this' is the {@link android.content.Context} +// The fileUrl is a string URL, such as "http://www.example.com/image.png" +Intent downloadIntent = new Intent(this, DownloadService.class); +downloadIntent.setData({@link android.net.Uri#parse Uri.parse}(fileUrl)); +startService(downloadIntent); +</pre> + +<p>O construtor {@link android.content.Intent#Intent(Context,Class)} + fornece {@link android.content.Context} ao aplicativo +e um objeto {@link java.lang.Class} ao componente. Assim, +essa intenção inicia explicitamente a classe {@code DownloadService} no aplicativo.</p> + +<p>Para obter mais informações sobre a criação e inicialização de um serviço, consulte +o guia <a href="{@docRoot}guide/components/services.html">Serviços</a>.</p> + + + + +<h3 id="ExampleSend">Exemplo de intenção implícita</h3> + +<p>A intenção implícita especifica uma ação que possa chamar qualquer aplicativo no dispositivo capaz +de realizar a ação. A intenção implícita é útil quando o aplicativo não pode realizar +a ação, mas outros aplicativos provavelmente podem e o usuário seleciona que aplicativo usar.</p> + +<p>Por exemplo: se você tem o conteúdo que deseja que o usuário compartilhe com outras pessoas, crie uma intenção +com a ação {@link android.content.Intent#ACTION_SEND} +e adicione extras que especifiquem o conteúdo a compartilhar. Ao chamar +{@link android.content.Context#startActivity startActivity()} com esta intenção, o usuário poderá +selecionar um aplicativo pelo qual deseja compartilhar o conteúdo.</p> + +<p class="caution"><strong>Atenção:</strong> é possível que um usuário não tenha <em>nenhum</em> +aplicativo que trate da intenção implícita enviada a {@link android.content.Context#startActivity +startActivity()}. Se isso acontecer, a chamada e seu aplicativo falharão. Para verificar +se uma atividade receberá a intenção, chame {@link android.content.Intent#resolveActivity +resolveActivity()} no objeto {@link android.content.Intent}. Se o resultado não for nulo, +há pelo menos um aplicativo que pode tratar da intenção e será seguro chamar +{@link android.content.Context#startActivity startActivity()}. Se o resultado for nulo, +você não deve usar a intenção e, se possível, deve desativar o recurso que emite +a intenção.</p> + + +<pre> +// Create the text message with a string +Intent sendIntent = new Intent(); +sendIntent.setAction(Intent.ACTION_SEND); +sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); +sendIntent.setType({@link + org.apache.http.protocol.HTTP#PLAIN_TEXT_TYPE + HTTP.PLAIN_TEXT_TYPE}); // "text/plain" MIME type + +// Verify that the intent will resolve to an activity +if (sendIntent.resolveActivity(getPackageManager()) != null) { + startActivity(sendIntent); +} +</pre> + +<p class="note"><strong>Observação:</strong> nesse caso, não será usada nenhuma URI, mas o tipo de dados da intenção +será declarado para especificar o conteúdo carregado pelos extras.</p> + + +<p>Quando {@link android.content.Context#startActivity startActivity()} é chamada, o sistema +avalia todos os aplicativos instalados para determinar quais deles podem tratar esse tipo de intenção +(uma intenção com a ação {@link android.content.Intent#ACTION_SEND} e que carrega dados +de "texto/simples". Se houver somente um aplicativo que possa tratá-la, o aplicativo abre imediatamente e recebe +a intenção. Se diversas atividades aceitarem a intenção, o sistema +exibirá uma caixa de diálogo para que o usuário selecione que aplicativo usar.</p> + + +<div class="figure" style="width:200px"> + <img src="{@docRoot}images/training/basics/intent-chooser.png" alt=""> + <p class="img-caption"><strong>Figura 2.</strong> Caixa de diálogo seletora.</p> +</div> + +<h3 id="ForceChooser">Forçar um seletor de aplicativo</h3> + +<p>Quando há mais de um aplicativo que responde à intenção implícita, +o usuário pode selecionar o aplicativo que deseja usar e tornar este aplicativo a escolha padrão para +a ação. Isso é positivo ao executar uma ação para a qual o usuário +deseja usar o mesmo aplicativo todas as vezes, como quando abre uma página da web (os usuários +geralmente usam apenas um navegador).</p> + +<p>Contudo, se diversos aplicativos podem responder à intenção e o usuário deve ficar livre para usar um aplicativo +diferente em cada vez, é preciso exibir uma caixa de diálogo seletora explicitamente. A caixa de diálogo seletora pede que +o usuário selecione o aplicativo desejado para a ação todas as vezes (o usuário não pode selecionar um aplicativo padrão para +a ação). Por exemplo: quando o aplicativo realiza "compartilhar" com a ação {@link +android.content.Intent#ACTION_SEND}, os usuários podem querer compartilhar usando um aplicativo diferente +conforme a situação, portanto deve-se sempre usar a caixa de diálogo seletora, como ilustrado na figura 2.</p> + + + + +<p>Para exibir o seletor, crie uma {@link android.content.Intent} usando {@link +android.content.Intent#createChooser createChooser()} e passe-a para {@link +android.app.Activity#startActivity startActivity()}. Por exemplo:</p> + +<pre> +Intent sendIntent = new Intent(Intent.ACTION_SEND); +... + +// Always use string resources for UI text. +// This says something like "Share this photo with" +String title = getResources().getString(R.string.chooser_title); +// Create intent to show the chooser dialog +Intent chooser = Intent.createChooser(sendIntent, title); + +// Verify the original intent will resolve to at least one activity +if (sendIntent.resolveActivity(getPackageManager()) != null) { + startActivity(chooser); +} +</pre> + +<p>Isso exibe uma caixa de diálogo com uma lista de aplicativos que respondem à intenção transmitida ao método {@link +android.content.Intent#createChooser createChooser()} e utiliza o texto fornecido como +título da caixa de diálogo.</p> + + + + + + + + + +<h2 id="Receiving">Recepção de uma intenção implícita</h2> + +<p>Para anunciar quais intenções implícitas o aplicativo pode receber, declare um ou mais filtros de intenções +para cada um dos componentes do aplicativo com um elemento +<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> no <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">arquivo de manifesto</a>. +Cada filtro de intenções especifica o tipo de intenções aceito com base na ação +nos dados e na categoria da intenção. O sistema fornecerá uma intenção implícita ao componente do seu aplicativo somente se ela +puder passar por um dos filtros de intenções.</p> + +<p class="note"><strong>Observação:</strong> a intenção explícita é sempre entregue ao alvo +independentemente dos filtros de intenções que o componente declare.</p> + +<p>Os componentes de um aplicativo devem declarar filtros separados para cada trabalho exclusivo que podem fazer. +Por exemplo, uma atividade em um aplicativo de galeria de imagens pode ter dois filtros: um filtro +para visualizar uma imagem e outro para editar uma imagem. Quando a atividade inicia, +ela inspeciona a {@link android.content.Intent} e decide como se comportar com base nas informações +na {@link android.content.Intent} (como para exibir ou não os controles do editor).</p> + +<p>Cada filtro de intenções é definido por um elemento <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a> +no arquivo de manifesto do aplicativo, aninhado no componente correspondente do aplicativo (como +um elemento +<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>). Dentro de <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code <intent-filter>}</a>, +é possível especificar o tipo de intenções aceitas usando um ou mais +dos três elementos a seguir:</p> + +<dl> +<dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a></dt> + <dd>Declara a ação da intenção aceita, no atributo {@code name}. O valor + deve ser o valor literal da string de uma ação, e não a constante da classe.</dd> +<dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a></dt> + <dd>Declara o tipo de dados aceitos usando um ou mais atributos que especificam diversos + aspectos da URI de dados (<code>scheme</code>, <code>host</code>, <code>port</code>, +<code>path</code> etc.) e do tipo MIME.</dd> +<dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a></dt> + <dd>Declara a categoria da intenção aceita, no atributo {@code name}. O valor + deve ser o valor literal da string de uma ação, e não a constante da classe. + + <p class="note"><strong>Observação:</strong> para receber intenções implícitas, + <strong>é preciso incluir</strong> a + categoria {@link android.content.Intent#CATEGORY_DEFAULT} no filtro de intenções. Os métodos +{@link android.app.Activity#startActivity startActivity()} e +{@link android.app.Activity#startActivityForResult startActivityForResult()} tratam de todas as intenções + como se eles declarassem a categoria {@link android.content.Intent#CATEGORY_DEFAULT}. + Se você não a declarar no filtro de intenções, nenhuma intenção implícita retomará + a sua atividade.</p> + </dd> +</dl> + +<p>Por exemplo, abaixo há uma declaração de atividade com um filtro de intenções para receber +uma intenção {@link android.content.Intent#ACTION_SEND} quando o tipo de dados for texto:</p> + +<pre> +<activity android:name="ShareActivity"> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain"/> + </intent-filter> +</activity> +</pre> + +<p>Não há problemas em criar um filtro que inclua mais de uma instância de +<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code <action>}</a>, +<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> ou +<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code <category>}</a>. +Se você o fizer, basta certificar-se de que o componente possa tratar todas e quaisquer combinações +daqueles elementos do filtro.</p> + +<p>Para tratar de diversos tipos de intenções, mas somente em combinações específicas +de ações, dados e tipos de categoria, será necessário criar diversos filtros de intenções.</p> + + +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h2>Restrição de acesso a componentes</h2> +<p>O uso de filtros de intenção não é um modo seguro de evitar que outros aplicativos iniciem +componentes. Embora os filtros de intenções restrinjam um componente a responder somente +a determinados tipos de intenções implícitas, outro aplicativo pode iniciar o componente do aplicativo +usando uma intenção explícita se o desenvolvedor determinar os nomes dos componentes. +Se for importante que <em>somente determinado aplicativo</em> inicie um dos seus componentes, +defina o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#exported">{@code +exported}</a> como {@code "false"} para o componente em questão. +</p> +</div> +</div> + +<p>As intenções implícitas são testadas em relação a um filtro por meio da comparação da intenção com cada um +dos três elementos. Para ser entregue ao componente, a intenção deve passar por todos os três testes. +Se ela falhar em algum deles, o sistema Android não entregará a intenção +ao componente. No entanto, como um componente poder ter diversos filtros de intenções, uma intenção que não +passe por um dos filtros de um componente pode passar por outro filtro. +Veja mais informações sobre como o sistema resolve intenções na seção abaixo +sobre <a href="#Resolution">Resolução de intenções</a>.</p> + +<p class="caution"><strong>Atenção:</strong> para evitar a execução involuntária de um {@link android.app.Service} +diferente do aplicativo, sempre use uma intenção explícita para iniciar o próprio serviço +e não declare filtros de intenções para ele.</p> + +<p class="note"><strong>Observação:</strong> +para todas as atividades, é necessário declarar os filtros de intenções no arquivo de manifesto. +Contudo, os filtros para receptores de transmissão podem ser registrados dinamicamente chamando +{@link android.content.Context#registerReceiver(BroadcastReceiver, IntentFilter, String, +Handler) registerReceiver()}. Assim, será possível cancelar o registro do receptor com {@link +android.content.Context#unregisterReceiver unregisterReceiver()}. Isso permitirá que o aplicativo +receba transmissões específicas durante um período de tempo especificado apenas quando o aplicativo +estiver em execução.</p> + + + + + + + +<h3 id="ExampleFilters">Exemplos de filtros</h3> + +<p>Para compreender melhor alguns dos comportamentos do filtro de intenções, veja o fragmento a seguir +do arquivo de manifesto de um aplicativo de compartilhamento social.</p> + +<pre> +<activity android:name="MainActivity"> + <!-- This activity is the main entry, should appear in app launcher --> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> + +<activity android:name="ShareActivity"> + <!-- This activity handles "SEND" actions with text data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="text/plain"/> + </intent-filter> + <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data --> + <intent-filter> + <action android:name="android.intent.action.SEND"/> + <action android:name="android.intent.action.SEND_MULTIPLE"/> + <category android:name="android.intent.category.DEFAULT"/> + <data android:mimeType="application/vnd.google.panorama360+jpg"/> + <data android:mimeType="image/*"/> + <data android:mimeType="video/*"/> + </intent-filter> +</activity> +</pre> + +<p>A primeira atividade, {@code MainActivity}, é o ponto de entrada principal do aplicativo — a atividade +que abre quando o usuário inicializa o aplicativo pela primeira vez com o ícone de inicialização:</p> +<ul> + <li>A ação {@link android.content.Intent#ACTION_MAIN} + indica que este é o ponto de entrada principal e não espera nenhum dado de intenção.</li> + <li>A categoria {@link android.content.Intent#CATEGORY_LAUNCHER} indica que esse ícone + da atividade deve ser colocado no inicializador de aplicativo do sistema. Se o elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> + não especificar um ícone com {@code icon}, o sistema usará o ícone do elemento + <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>.</li> +</ul> +<p>Esses dois devem ser pareados juntos para que a atividade apareça no inicializador do aplicativo.</p> + +<p>A segunda atividade, {@code ShareActivity}, destina-se a facilitar o compartilhamento de conteúdo de texto +e mídia. Apesar de os usuários poderem acessar essa atividade pela {@code MainActivity}, +eles também podem acessar {@code ShareActivity} diretamente de outro aplicativo que emita uma intenção +implícita que corresponda a um dos dois filtros de intenções.</p> + +<p class="note"><strong>Observação:</strong> o tipo MIME, +<a href="https://developers.google.com/panorama/android/">{@code +application/vnd.google.panorama360+jpg}</a>, é um tipo de dados especial que especifica +fotos panorâmicas que podem ser tratadas com as APIs do <a href="{@docRoot}reference/com/google/android/gms/panorama/package-summary.html">Google +Panorama</a>.</p> + + + + + + + + + + + + + +<h2 id="PendingIntent">Uso de uma intenção pendente</h2> + +<p>Um objeto {@link android.app.PendingIntent} é um agrupador em torno de um objeto {@link +android.content.Intent}. A principal finalidade de uma {@link android.app.PendingIntent} + é conceder permissão a um aplicativo externo +para usar a {@link android.content.Intent} contida como se ela fosse executada a partir +do processo do próprio aplicativo.</p> + +<p>Os principais casos de uso de uma intenção pendente são:</p> +<ul> + <li>Declarar uma intenção a ser executada quando o usuário realiza uma ação com a <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notificação</a> + (o {@link android.app.NotificationManager} do sistema Android + executa a {@link android.content.Intent}). + <li>Declarar uma intenção a ser executada quando o usuário realiza uma ação com o + <a href="{@docRoot}guide/topics/appwidgets/index.html">Widget do aplicativo</a> + (o aplicativo de tela inicial executa a {@link android.content.Intent}). + <li>Declarar uma intenção a ser executada em um momento específico no futuro (o {@link android.app.AlarmManager} + do sistema Android executa a {@link android.content.Intent}). +</ul> + +<p>Como cada objeto {@link android.content.Intent} é projetado para ser tratado por um tipo +específico de componentes do aplicativo (uma {@link android.app.Activity}, um {@link android.app.Service} +ou um {@link android.content.BroadcastReceiver}), uma {@link android.app.PendingIntent} +deve ser criada com a mesma consideração. Ao usar uma intenção pendente, o aplicativo +não executará a intenção com uma chamada como de {@link android.content.Context#startActivity +startActivity()}. Em vez disso, deve-se declarar o tipo do componente pretendido ao criar +a {@link android.app.PendingIntent} chamando o respectivo método criador:</p> + +<ul> + <li>{@link android.app.PendingIntent#getActivity PendingIntent.getActivity()} para uma + {@link android.content.Intent} que inicia uma {@link android.app.Activity}.</li> + <li>{@link android.app.PendingIntent#getService PendingIntent.getService()} para uma + {@link android.content.Intent} que inicia um {@link android.app.Service}.</li> + <li>{@link android.app.PendingIntent#getBroadcast PendingIntent.getBroadcast()} para uma + {@link android.content.Intent} que inicia um {@link android.content.BroadcastReceiver}.</li> +</ul> + +<p>A menos que o aplicativo esteja <em>recebendo</em> intenções pendentes de outros aplicativos, +os métodos acima para criar uma {@link android.app.PendingIntent} são provavelmente +os únicos métodos de {@link android.app.PendingIntent} necessários.</p> + +<p>Cada método toma o {@link android.content.Context} do aplicativo atual, +a {@link android.content.Intent} que você deseja agrupar e um ou mais sinalizadores que especificam +como a intenção deve ser usada (como se a intenção pudesse ser usada mais de uma vez).</p> + +<p>Veja mais informações sobre o uso de intenções pendentes na documentação +dos respectivos casos de uso, como nos guias das APIs de <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notificações</a> +e <a href="{@docRoot}guide/topics/appwidgets/index.html">Widget do aplicativo</a>.</p> + + + + + + + +<h2 id="Resolution">Resolução de intenções</h2> + + +<p>Quando o sistema recebe uma intenção implícita para iniciar uma atividade, ele busca +as melhores atividades para a intenção comparando-a com os filtros de intenções com base em três aspectos:</p> + +<ul> + <li>A ação da intenção + <li>Os dados da intenção (URI e tipo de dados) + <li>A categoria da intenção +</ul> + +<p>As seções a seguir descrevem como uma intenção é combinada com os componentes apropriados +em termos de como o filtro de intenções é declarado no arquivo de manifesto de um aplicativo.</p> + + +<h3 id="ActionTest">Teste de ação</h3> + +<p>Para especificar ações de intenções aceitas, um filtro de intenções pode declarar zero ou mais +elementos <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code +<action>}</a>. Por exemplo:</p> + +<pre> +<intent-filter> + <action android:name="android.intent.action.EDIT" /> + <action android:name="android.intent.action.VIEW" /> + ... +</intent-filter> +</pre> + +<p>Para passar por este filtro, a ação especificada na {@link android.content.Intent} + deve corresponder a uma das ações listadas no filtro.</p> + +<p>Se o filtro não listar nenhuma ação, não há nada a que +uma intenção corresponda, portanto todas as intenções falharão no teste. Contudo, se uma {@link android.content.Intent} +não especificar nenhuma ação, ela passará no teste (desde que o filtro +contenha pelo menos uma ação).</p> + + + +<h3 id="CategoryTest">Teste de categoria</h3> + +<p>Para especificar as categorias de intenção aceitas, um filtro de intenções pode declarar zero ou mais +elementos <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code +<category>}</a>. Por exemplo:</p> + +<pre> +<intent-filter> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + ... +</intent-filter> +</pre> + +<p>Para que uma intenção passe no teste de categoria, cada categoria na {@link android.content.Intent} +deve corresponder a uma categoria no filtro. O inverso não é necessário — o filtro de intenções pode +declarar mais categorias das especificadas na {@link android.content.Intent} e +a {@link android.content.Intent} ainda passará no teste. Portanto, uma intenção sem categorias sempre +passará nesse teste independentemente das categorias declaradas no filtro.</p> + +<p class="note"><strong>Observação:</strong> +O Android aplica automaticamente a categoria {@link android.content.Intent#CATEGORY_DEFAULT} +para todas as intenções implícitas passadas a {@link +android.content.Context#startActivity startActivity()} e {@link +android.app.Activity#startActivityForResult startActivityForResult()}. +Por isso, se você deseja que a atividade receba intenções implícitas, ela deve +conter uma categoria de {@code "android.intent.category.DEFAULT"} nos filtros de intenções (como +exibido no exemplo de {@code <intent-filter>} anterior).</p> + + + +<h3 id="DataTest">Teste de dados</h3> + +<p>Para especificar dados de intenções aceitas, um filtro de intenções pode declarar zero ou mais +elementos <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code +<data>}</a>. Por exemplo:</p> + +<pre> +<intent-filter> + <data android:mimeType="video/mpeg" android:scheme="http" ... /> + <data android:mimeType="audio/mpeg" android:scheme="http" ... /> + ... +</intent-filter> +</pre> + +<p>Cada elemento +<code><a href="{@docRoot}guide/topics/manifest/data-element.html"><data></a></code> pode especificar uma estrutura de URI e um tipo de dados (tipo de mídia MIME). Há atributos +separados — {@code scheme}, {@code host}, {@code port} e +{@code path} — para cada parte da URI: +</p> + +<p style="margin-left: 2em">{@code <scheme>://<host>:<port>/<path>}</p> + +<p> +Por exemplo: +</p> + +<p style="margin-left: 2em">{@code content://com.example.project:200/folder/subfolder/etc}</p> + +<p>Nessa URI, o esquema é {@code content}, o host é {@code com.example.project}, +a porta é {@code 200} e o caminho é {@code folder/subfolder/etc}. +</p> + +<p>Cada um desses atributos é opcional em um elemento <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>, +mas há dependências lineares:</p> +<ul> + <li>Se não houver esquema especificado, o host será ignorado.</li> + <li>Se não houver host especificado, a porta será ignorada.</li> + <li>Se não houver esquema nem host especificado, o caminho será ignorado.</li> +</ul> + +<p>Quando a URI em uma intenção é comparada a uma especificação de URI em um filtro, +a comparação é feita somente com as partes da URI incluídas no filtro. Por exemplo:</p> +<ul> + <li>Se um filtro especificar somente um esquema, todas as URIs com esse esquema atenderão +ao filtro.</li> + <li>Se um filtro especificar um esquema e uma autoridade, mas não um caminho, todas as URIs +com o mesmo esquema e autoridade passarão pelo filtro independentemente dos caminhos.</li> + <li>Se um filtro especificar um esquema, uma autoridade e um caminho, somente URIs com o mesmo esquema, +autoridade e caminho passarão pelo filtro.</li> +</ul> + +<p class="note"><strong>Observação:</strong> a especificação de caminho pode +conter um asterisco especial (*) para exigir somente uma correspondência parcial do nome do caminho.</p> + +<p>O teste de dados compara a URI e o tipo MIME da intenção com uma URI +e um tipo MIME especificados no filtro. As regras são as seguintes: +</p> + +<ol type="a"> +<li>A intenção que não contiver URI nem tipo MIME passará +no teste somente se o filtro não especificar nenhuma URI nem tipo MIME.</li> + +<li>A intenção que contiver URI mas nenhum tipo MIME (nem explícito, nem inferível a partir +da URI) passará pelo teste somente se a URI corresponder ao formato de URI do filtro +e se o filtro, igualmente, não especificar um tipo MIME.</li> + +<li>A intenção que contiver tipo MIME mas nenhuma URI passará pelo teste +somente se o filtro listar o mesmo tipo MIME e não especificar nenhum formato de URI.</li> + +<li>A intenção que contiver URI e tipo MIME (explícito ou inferível a partir +da URI) passará a parte do tipo MIME do teste somente se esse +tipo corresponder a um tipo listado no filtro. A parte da URI passará no teste +se corresponder a uma URI no filtro ou se tiver uma URI de {@code content:} +ou {@code file:} e se o filtro não especificar nenhuma URI. Em outras palavras, +presume-se que um componente seja compatível com dados de {@code content:} e de {@code file:} se +o filtro listar <em>somente</em> um tipo MIME.</p></li> +</ol> + +<p> +Essa última regra (d) reflete a expectativa +de que os componentes sejam capazes de obter dados de local de um arquivo ou provedor de conteúdo. +Portanto, os filtros podem listar somente um tipo de dados e não precisam nomear +explicitamente os esquemas {@code content:} e {@code file:}. +Este é um caso típico. Um elemento <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a> +como o seguinte, por exemplo, informa ao Android que o componente pode obter dados de imagem de um provedor +de conteúdo e exibi-los: +</p> + +<pre> +<intent-filter> + <data android:mimeType="image/*" /> + ... +</intent-filter></pre> + +<p> +Como a maioria dos dados disponíveis é dispensada pelos provedores de conteúdo, os filtros +que especificam um tipo de dados mas não uma URI são, talvez, os mais comuns. +</p> + +<p> +Outra configuração comum é: filtros com um esquema e um tipo de dados. Por +exemplo, um elemento +<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code <data>}</a>, como o seguinte, informa ao Android +que o componente pode recuperar dados de vídeo da rede para realizar a ação: +</p> + +<pre> +<intent-filter> + <data android:scheme="http" android:type="video/*" /> + ... +</intent-filter></pre> + + + +<h3 id="imatch">Correspondência de intenções</h3> + +<p>Intenções são correspondidas a filtros de intenções não somente para descobrir +um componente-alvo a ativar, mas também para descobrir algo sobre o conjunto +de componentes do dispositivo. Por exemplo: o aplicativo Home preenche o inicializador do aplicativo +encontrando todas as atividades com filtros de intenções que especifiquem +a ação {@link android.content.Intent#ACTION_MAIN} e +a categoria {@link android.content.Intent#CATEGORY_LAUNCHER}.</p> + +<p>O aplicativo pode usar a correspondência de intenções de modo similar. +O {@link android.content.pm.PackageManager} tem um conjunto de métodos +{@code query...()}, que retornam todos os componentes que podem aceitar uma determinada intenção +e uma série de métodos {@code resolve...()} similares, que determinam o melhor +componente para responder a uma intenção. Por exemplo: +{@link android.content.pm.PackageManager#queryIntentActivities +queryIntentActivities()} retorna uma lista de todas as atividades que podem realizar +a intenção passada como um argumento e {@link +android.content.pm.PackageManager#queryIntentServices +queryIntentServices()} retorna uma lista de serviços semelhantes. +Nenhum dos métodos ativa os componentes — eles apenas listam aqueles que +podem responder. Há um método semelhante +para receptores de transmissão — o {@link android.content.pm.PackageManager#queryBroadcastReceivers +queryBroadcastReceivers()}. +</p> + + + + diff --git a/docs/html-intl/intl/pt-br/guide/components/loaders.jd b/docs/html-intl/intl/pt-br/guide/components/loaders.jd new file mode 100644 index 000000000000..f3c42094729d --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/loaders.jd @@ -0,0 +1,494 @@ +page.title=Carregadores +parent.title=Atividades +parent.link=activities.html +@jd:body +<div id="qv-wrapper"> +<div id="qv"> + <h2>Neste documento</h2> + <ol> + <li><a href="#summary">Resumo de API de carregador</a></li> + <li><a href="#app">Uso de carregadores em um aplicativo</a> + <ol> + <li><a href="#requirements"></a></li> + <li><a href="#starting">Início de um carregador</a></li> + <li><a href="#restarting">Reinício de um carregador</a></li> + <li><a href="#callback">Uso dos retornos de chamada de LoaderManager</a></li> + </ol> + </li> + <li><a href="#example">Exemplo</a> + <ol> + <li><a href="#more_examples">Mais exemplos</a></li> + </ol> + </li> + </ol> + + <h2>Classes principais</h2> + <ol> + <li>{@link android.app.LoaderManager}</li> + <li>{@link android.content.Loader}</li> + + </ol> + + <h2>Exemplos relacionados</h2> + <ol> + <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html"> +LoaderCursor</a></li> + <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> +LoaderThrottle</a></li> + </ol> + </div> +</div> + +<p>Introduzidos no Android 3.0, os carregadores facilitam o carregamento assíncrono de dados +em uma atividade ou fragmento. Os carregadores têm as seguintes características:</p> + <ul> + <li>Eles estão disponíveis para cada {@link android.app.Activity} e {@link +android.app.Fragment}.</li> + <li>Eles fornecem carregamento assíncrono de dados.</li> + <li>Eles monitoram a origem dos dados e fornecem novos resultados +quando o conteúdo é alterado.</li> + <li>Eles reconectam-se automaticamente ao cursor do último carregador +quando são recriados após uma alteração de configuração. Portanto, eles não precisam reconsultar +os dados.</li> + </ul> + +<h2 id="summary">Resumo da API de carregador</h2> + +<p>Há várias classes e interfaces que podem ser envolvidas no uso +de carregadores em um aplicativo. Elas são resumidas nesta tabela:</p> + +<table> + <tr> + <th>Classe/Interface</th> + <th>Descrição</th> + </tr> + <tr> + <td>{@link android.app.LoaderManager}</td> + <td>Uma classe abstrata associada a {@link android.app.Activity} ou +{@link android.app.Fragment} para gerenciar uma ou mais instâncias de {@link +android.content.Loader}. Isto ajuda um aplicativo a gerenciar +operações executadas por longos períodos juntamente com o ciclo de vida de {@link android.app.Activity} +ou {@link android.app.Fragment}; o uso mais comum disto é com +{@link android.content.CursorLoader}. No entanto, os aplicativos têm a liberdade de criar +os próprios carregadores para outros tipos de dados. + <br /> + <br /> + Há apenas um {@link android.app.LoaderManager} por atividade ou fragmento. No entanto, um {@link android.app.LoaderManager} pode ter +vários carregadores.</td> + </tr> + <tr> + <td>{@link android.app.LoaderManager.LoaderCallbacks}</td> + <td>Uma interface de retorno de chamada para um cliente interagir com {@link +android.app.LoaderManager}. Por exemplo, usa-se o método de retorno de chamada {@link +android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} +para criar um novo carregador.</td> + </tr> + <tr> + <td>{@link android.content.Loader}</td> + <td>Uma classe abstrata que realiza carregamento assíncrono de dados. Esta é a classe de base +de um carregador. Geralmente, você usaria {@link +android.content.CursorLoader}, mas é possível implementar subclasse própria. Enquanto os carregadores +estiverem ativos, devem monitorar a origem dos dados e fornecer +novos resultados quando o conteúdo for alterado. </td> + </tr> + <tr> + <td>{@link android.content.AsyncTaskLoader}</td> + <td>Um carregador abstrato que fornece uma {@link android.os.AsyncTask} para realizar o trabalho.</td> + </tr> + <tr> + <td>{@link android.content.CursorLoader}</td> + <td>Uma subclasse de {@link android.content.AsyncTaskLoader} que consulta +{@link android.content.ContentResolver} e retorna um {@link +android.database.Cursor}. Esta classe implementa o protocolo {@link +android.content.Loader} de forma padrão para cursores de consulta, +compilando em {@link android.content.AsyncTaskLoader} para realizar a consulta de cursor +em um encadeamento de segundo plano para que a IU do aplicativo não seja bloqueada. Usar +este carregador é a melhor maneira de carregar dados de forma assíncrona a partir de um {@link +android.content.ContentProvider}, em vez de realizar uma consulta gerenciada pelas +APIs da atividade ou do fragmento.</td> + </tr> +</table> + +<p>As classes e interfaces na tabela acima são os componentes essenciais +que você usará para implementar um carregador no aplicativo. Você não precisará de todos eles +para cada carregador criado, mas sempre precisará de uma referência a {@link +android.app.LoaderManager} para inicializar um carregador e uma implementação +de uma classe {@link android.content.Loader}, como {@link +android.content.CursorLoader}. As seguintes seções mostram como usar +essas classes e interfaces em um aplicativo.</p> + +<h2 id ="app">Uso de carregadores em um aplicativo</h2> +<p>Esta seção descreve como usar os carregadores em um aplicativo do Android. Um aplicativo +que usa os carregadores, geralmente, inclui o seguinte:</p> +<ul> + <li>Uma {@link android.app.Activity} ou um {@link android.app.Fragment}.</li> + <li>Uma instância de {@link android.app.LoaderManager}.</li> + <li>Um {@link android.content.CursorLoader} para carregar dados baseados em um {@link +android.content.ContentProvider}. Alternativamente, é possível implementar a própria subclasse +de {@link android.content.Loader} ou {@link android.content.AsyncTaskLoader} +para carregar dados de outra origem.</li> + <li>Uma implementação de {@link android.app.LoaderManager.LoaderCallbacks}. +É aqui que é possível criar novos carregadores e gerenciar as referências +a carregadores existentes.</li> +<li>Uma maneira de exibir os dados do carregador, como um {@link +android.widget.SimpleCursorAdapter}.</li> + <li>Uma origem de dados, como um {@link android.content.ContentProvider}, ao usar +{@link android.content.CursorLoader}.</li> +</ul> +<h3 id="starting">Início de um carregador</h3> + +<p>O {@link android.app.LoaderManager} gerencia uma ou mais instâncias de {@link +android.content.Loader} dentro de uma {@link android.app.Activity} +ou um {@link android.app.Fragment}. Há apenas um {@link +android.app.LoaderManager} por atividade ou fragmento.</p> + +<p>Geralmente, +inicializa-se um {@link android.content.Loader} dentro do método {@link +android.app.Activity#onCreate onCreate()} da atividade, ou dentro do método +{@link android.app.Fragment#onActivityCreated onActivityCreated()} do fragmento. Faça +isso da seguinte maneira:</p> + +<pre>// Prepare the loader. Either re-connect with an existing one, +// or start a new one. +getLoaderManager().initLoader(0, null, this);</pre> + +<p>O método {@link android.app.LoaderManager#initLoader initLoader()} +recebe os seguintes parâmetros:</p> +<ul> + <li>Um ID único que identifica o carregador. Neste exemplo, o ID é 0.</li> +<li>Argumentos opcionais para fornecer ao carregador +em construção (<code>null</code> neste exemplo).</li> + +<li>Uma implementação de {@link android.app.LoaderManager.LoaderCallbacks}, +que {@link android.app.LoaderManager} chama para relatar eventos do carregador. Nesse exemplo, + a classe local implementa a interface de {@link +android.app.LoaderManager.LoaderCallbacks}, para que ela passe uma referência +para si, {@code this}.</li> +</ul> +<p>A chamada de {@link android.app.LoaderManager#initLoader initLoader()} garante que o carregador +foi inicializado e que está ativo. Ela possui dois possíveis resultados:</p> +<ul> + <li>Se o carregador especificado pelo ID já existir, o último carregador +criado será usado novamente.</li> + <li>Se o carregador especificado pelo ID <em>não</em> existir, +{@link android.app.LoaderManager#initLoader initLoader()} ativará o método +{@link android.app.LoaderManager.LoaderCallbacks} {@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}. +É aqui que você implementa o código para instanciar e retornar um novo carregador. +Para obter mais informações, consulte a seção <a href="#onCreateLoader">onCreateLoader</a>.</li> +</ul> +<p>Em qualquer um dos casos, a implementação de {@link android.app.LoaderManager.LoaderCallbacks} +fornecida é associada ao carregador e será chamada quando o estado +do carregador mudar. Se, no momento desta chamada, o autor dela +estiver no estado inicializado e o carregador solicitado já existir e tiver +gerado seus dados, o sistema chamará {@link +android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()} +imediatamente (durante{@link android.app.LoaderManager#initLoader initLoader()}), +então prepare-se para tais situações. Consulte <a href="#onLoadFinished"> +onLoadFinished</a> para obter mais informações sobre este retorno de chamada</p> + +<p>Observe que o método {@link android.app.LoaderManager#initLoader initLoader()} +retorna o {@link android.content.Loader} que é criado, mas você não precisará +capturar uma referência para ele. O {@link android.app.LoaderManager} gerencia +a vida do carregador automaticamente. O {@link android.app.LoaderManager} +inicia e interrompe o carregamento quando necessário, além de manter o estado do carregador +e do conteúdo associado. À medida que isso ocorre, você raramente interage com os carregadores +diretamente (para ver um exemplo de métodos para aprimorar o comportamento +de um carregador, consulte o exemplo de <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a>). +Geralmente, usam-se os métodos {@link +android.app.LoaderManager.LoaderCallbacks} para intervir no processo de carregamento +quando determinados eventos ocorrem. Para obter mais informações sobre este assunto, consulte <a href="#callback">Uso dos retornos de chamada de LoaderManager</a>.</p> + +<h3 id="restarting">Reinício de um carregador</h3> + +<p>Ao usar {@link android.app.LoaderManager#initLoader initLoader()}, +como mostrado acima, ele usará um carregador existente com o ID especificado, se houver um. +Caso contrário, um carregador será criado. No entanto, às vezes, você quer descartar os dados antigos +e começar do início.</p> + +<p>Para descartar os dados antigos, use {@link +android.app.LoaderManager#restartLoader restartLoader()}. Por exemplo, +esta implementação de {@link android.widget.SearchView.OnQueryTextListener} reinicia +o carregador quando a consulta do usuário é alterada. O carregador precisa ser reiniciado +para que possa usar o filtro de busca revisado para realizar uma nova consulta:</p> + +<pre> +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; +}</pre> + +<h3 id="callback">Uso dos retornos de chamada de LoaderManager</h3> + +<p>{@link android.app.LoaderManager.LoaderCallbacks} é uma interface de retorno de chamada +que permite que um cliente interaja com o {@link android.app.LoaderManager}. </p> +<p>Carregadores, em determinado {@link android.content.CursorLoader}, devem +reter os dados após serem interrompidos. Isto permite que os aplicativos +mantenham os dados dos métodos {@link android.app.Activity#onStop +onStop()} e {@link android.app.Activity#onStart onStart()} do fragmento ou da atividade +para que, quando os usuários voltarem a um aplicativo, não tenham que esperar +o recarregamento dos dados. Você usa os métodos {@link android.app.LoaderManager.LoaderCallbacks} +para saber quando deve criar um novo carregador, e para dizer ao aplicativo quando + deve interromper o uso dos dados de um carregador.</p> + +<p>{@link android.app.LoaderManager.LoaderCallbacks} inclui +esses métodos:</p> +<ul> + <li>{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} — +instancia e retorna um novo {@link android.content.Loader} para o ID fornecido. +</li></ul> +<ul> + <li> {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()} +— chamado quando um carregador anteriormente criado termina o seu carregamento. +</li></ul> +<ul> + <li>{@link android.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()} + — chamado quando um carregador anteriormente criado é reiniciado, +tornando os dados indisponíveis. +</li> +</ul> +<p>Esses métodos são descritos com mais informações nas seguintes seções.</p> + +<h4 id ="onCreateLoader">onCreateLoader</h4> + +<p>Ao tentar acessar um carregador (por exemplo, por meio de {@link +android.app.LoaderManager#initLoader initLoader()}), ele verifica +se o carregador especificado pelo ID existe. Se não existir, ele ativa o método {@link +android.app.LoaderManager.LoaderCallbacks} {@link +android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}. É aqui +que você pode criar um novo carregador. Geralmente, será um {@link +android.content.CursorLoader}, mas é possível implementar a própria subclasse de {@link +android.content.Loader}. </p> + +<p>Nesse exemplo, o método de retorno de chamada de {@link +android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} +cria um {@link android.content.CursorLoader}. Você deve compilar +{@link android.content.CursorLoader} usando o método construtor, +que exige um conjunto completo de informações necessárias para realizar uma consulta ao {@link +android.content.ContentProvider}. Especificamente, ele precisa de:</p> +<ul> + <li><em>uri</em> — a URI do conteúdo a ser recuperado. </li> + <li><em>projection</em> — uma lista de quais colunas devem ser retornadas. Passar +<code>null</code> retornará todas as colunas, o que é ineficiente. </li> + <li><em>selection</em> — um filtro que declara quais linhas devem retornar, +formatado por uma cláusula SQL WHERE (excluindo WHERE). Passar +<code>null</code> retornará todas as linhas da URI em questão. </li> + <li><em>selectionArgs</em> — é possível incluir interrogações na seleção, +que serão substituídas pelos valores de <em>selectionArgs</em>, na ordem em que aparecem +na seleção. Os valores serão vinculados como Strings. </li> + <li><em>sortOrder</em> — como ordenar as linhas, formatadas em uma cláusula SQL +ORDER BY (excluindo ORDER BY). Passar <code>null</code> +usará a ordem de classificação padrão, que pode ser desordenada.</li> +</ul> +<p>Por exemplo:</p> +<pre> + // If non-null, this is the current filter the user has provided. +String mCurFilter; +... +public Loader<Cursor> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri; + if (mCurFilter != null) { + baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, + Uri.encode(mCurFilter)); + } else { + baseUri = Contacts.CONTENT_URI; + } + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + + Contacts.DISPLAY_NAME + " != '' ))"; + return new CursorLoader(getActivity(), baseUri, + CONTACTS_SUMMARY_PROJECTION, select, null, + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); +}</pre> +<h4 id="onLoadFinished">onLoadFinished</h4> + +<p>Este método é chamado quando um carregador anteriormente criado terminar o seu carregamento. +Este método certamente será chamado antes da liberação dos últimos dados +que forem fornecidos por este carregador. Neste ponto, você deve remover todo o uso +dos dados antigos (já que serão liberados em breve), mas não deve fazer +a liberação dos dados, já que pertencem ao carregador e ele lidará com isso.</p> + + +<p>O carregador liberará os dados quando souber +que o aplicativo não está mais usando-os. Por exemplo, se os dados forem um cursor de um {@link +android.content.CursorLoader}, você não deve chamar {@link +android.database.Cursor#close close()} por conta própria. Se o cursor estiver +sendo colocado em um {@link android.widget.CursorAdapter}, você deve usar o método {@link +android.widget.SimpleCursorAdapter#swapCursor swapCursor()} para que o antigo +{@link android.database.Cursor} não seja fechado. Por exemplo:</p> + +<pre> +// This is the Adapter being used to display the list's data.<br +/>SimpleCursorAdapter mAdapter; +... + +public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); +}</pre> + +<h4 id="onLoaderReset">onLoaderReset</h4> + +<p>Este método é chamado quando um carregador anteriormente criado é reiniciado, +tornando os dados indisponíveis. Este retorno de chamada permite que você descubra quando os dados +estão prestes a serem liberados para que seja possível remover a referência a eles. </p> +<p>Esta implementação chama +{@link android.widget.SimpleCursorAdapter#swapCursor swapCursor()} +com um valor de <code>null</code>:</p> + +<pre> +// This is the Adapter being used to display the list's data. +SimpleCursorAdapter mAdapter; +... + +public void onLoaderReset(Loader<Cursor> loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); +}</pre> + + +<h2 id="example">Exemplo</h2> + +<p>Como exemplo, a seguir há uma implementação completa de um {@link +android.app.Fragment} que exibe uma {@link android.widget.ListView} contendo +os resultados de uma consulta aos provedores de conteúdo de contatos. Ela usa um {@link +android.content.CursorLoader} para gerenciar a consulta no provedor.</p> + +<p>Para um aplicativo acessar os contatos de um usuário, como neste exemplo, +o manifesto deverá incluir a permissão +{@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS}.</p> + +<pre> +public static class CursorLoaderListFragment extends ListFragment + implements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> { + + // This is the Adapter being used to display the list's data. + SimpleCursorAdapter mAdapter; + + // If non-null, this is the current filter the user has provided. + String mCurFilter; + + @Override public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText("No phone numbers"); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + // Create an empty adapter we will use to display the loaded data. + mAdapter = new SimpleCursorAdapter(getActivity(), + android.R.layout.simple_list_item_2, null, + new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, + new int[] { android.R.id.text1, android.R.id.text2 }, 0); + setListAdapter(mAdapter); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + // Place an action bar item for searching. + MenuItem item = menu.add("Search"); + item.setIcon(android.R.drawable.ic_menu_search); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + SearchView sv = new SearchView(getActivity()); + sv.setOnQueryTextListener(this); + item.setActionView(sv); + } + + public boolean onQueryTextChange(String newText) { + // Called when the action bar search text has changed. Update + // the search filter, and restart the loader to do a new query + // with this filter. + mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; + getLoaderManager().restartLoader(0, null, this); + return true; + } + + @Override public boolean onQueryTextSubmit(String query) { + // Don't care about this. + return true; + } + + @Override public void onListItemClick(ListView l, View v, int position, long id) { + // Insert desired behavior here. + Log.i("FragmentComplexList", "Item clicked: " + id); + } + + // These are the Contacts rows that we will retrieve. + static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { + Contacts._ID, + Contacts.DISPLAY_NAME, + Contacts.CONTACT_STATUS, + Contacts.CONTACT_PRESENCE, + Contacts.PHOTO_ID, + Contacts.LOOKUP_KEY, + }; + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + // First, pick the base URI to use depending on whether we are + // currently filtering. + Uri baseUri; + if (mCurFilter != null) { + baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, + Uri.encode(mCurFilter)); + } else { + baseUri = Contacts.CONTENT_URI; + } + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + + Contacts.DISPLAY_NAME + " != '' ))"; + return new CursorLoader(getActivity(), baseUri, + CONTACTS_SUMMARY_PROJECTION, select, null, + Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); + } + + public void onLoadFinished(Loader<Cursor> loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + } + + public void onLoaderReset(Loader<Cursor> loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } +}</pre> +<h3 id="more_examples">Mais exemplos</h3> + +<p>Há alguns exemplos variados na <strong>ApiDemos</strong> +que ilustra o uso de carregadores:</p> +<ul> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html"> +LoaderCursor</a> — uma versão completa do +fragmento exibido acima.</li> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — um exemplo de como usar o regulador +para reduzir o número de consultas que o provedor de conteúdo realiza quando os dados são alterados.</li> +</ul> + +<p>Para obter mais informações sobre o download e a instalação de exemplos de SDK, consulte <a href="http://developer.android.com/resources/samples/get.html">Obtenção +dos exemplos</a>. </p> + diff --git a/docs/html-intl/intl/pt-br/guide/components/processes-and-threads.jd b/docs/html-intl/intl/pt-br/guide/components/processes-and-threads.jd new file mode 100644 index 000000000000..c8e636dacce8 --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/processes-and-threads.jd @@ -0,0 +1,411 @@ +page.title=Processos e encadeamentos +page.tags=lifecycle,background + +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>Neste documento</h2> +<ol> +<li><a href="#Processes">Processos</a> + <ol> + <li><a href="#Lifecycle">Ciclo de vida dos processos</a></li> + </ol> +</li> +<li><a href="#Threads">Encadeamentos</a> + <ol> + <li><a href="#WorkerThreads">Encadeamentos de trabalho</a></li> + <li><a href="#ThreadSafe">Métodos seguros de encadeamento</a></li> + </ol> +</li> +<li><a href="#IPC">Comunicação entre processos</a></li> +</ol> + +</div> +</div> + +<p>Quando um componente de aplicativo inicia e o aplicativo não tem nenhum outro componente em execução, +o sistema Android inicia um novo processo no Linux para o aplicativo com um único encadeamento +de execução. Por padrão, todos os componentes do mesmo aplicativo são executados no mesmo processo +e encadeamento (chamado de encadeamento "principal"). Se um componente de aplicativo iniciar e já existir um processo +para este aplicativo (pois outro componente do aplicativo já existe), ele será iniciado +dentro deste processo e usará o mesmo encadeamento de execução. No entanto, é possível organizar para que vários componentes +no aplicativo sejam executados em processos separados e criar encadeamentos +adicionais para qualquer processo.</p> + +<p>Este documento discute como os processos e os encadeamentos funcionam em um aplicativo do Android.</p> + + +<h2 id="Processes">Processos</h2> + +<p>Por padrão, todos os componentes do mesmo aplicativo são executados no mesmo processo +e a maioria dos aplicativos não deve alterar isso. No entanto, se achar que precisa de controle sobre o processo a que um certo +componente pertence, é possível fazer isto no arquivo de manifesto.</p> + +<p>A entrada do manifesto para cada tipo de elemento de componente — <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code +<activity>}</a>, <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code +<service>}</a>, <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code +<receiver>}</a> e <a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code +<provider>}</a> — é compatível com um atributo {@code android:process} que pode especificar +um processo em que este componente deverá ser executado. É possível definir este atributo para que cada componente +seja executado em seu próprio processo ou para que alguns componentes compartilhem um processo, enquanto que outros não. Também é possível definir +{@code android:process} para que os componentes de aplicativos diferentes sejam executados no mesmo +processo — fornecido para que os aplicativos compartilhem o mesmo ID de usuário do Linux e sejam assinados +com os mesmos certificados.</p> + +<p>O elemento <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code +<application>}</a> também suporta um atributo {@code android:process} +para definir um valor padrão que se aplique a todos os elementos.</p> + +<p>O Android pode decidir desativar um processo em certo ponto, quando a memória estiver baixa e for necessária +para outros processos que atendem o usuário de forma mais imediata. Os componentes +de aplicativo em execução no processo que é eliminado são consequentemente eliminados. Um processo é iniciado +novamente para aqueles componentes quando houver trabalho para eles.</p> + +<p>Ao decidir que processo eliminar, o sistema Android avalia a importância relativa dele +para o usuário. Por exemplo, ele fechará mais prontamente um processo que hospede atividades que não estejam mais +visíveis na tela, comparado a um processo que hospede atividades visíveis. A decisão +é exterminar processo ou não, portanto, depende do estado dos componentes em execução neste processo. As regras +usadas para decidir quais processos serão exterminados são discutidas abaixo. </p> + + +<h3 id="Lifecycle">Ciclo de vida dos processos</h3> + +<p>O sistema Android tenta manter um processo do aplicativo pelo maior período possível, +mas eventualmente precisa remover processos antigos para recuperar memória para processos novos e mais importantes. Para determinar +quais processos manter +e quais exterminar, o sistema posiciona cada um em uma "hierarquia de importância" com base +nos componentes em execução e no estado deles. Processos com menos importância +serão eliminados primeiro e, em seguida, aqueles com a menor importância depois deles também serão, consecutivamente, até que os recursos +do sistema sejam recuperados.</p> + +<p>Há cinco níveis na hierarquia de importância. A lista a seguir mostra os tipos +de processo em ordem de importância (o primeiro processo é o <em>mais importante</em> +e o <em>eliminado por último</em>):</p> + +<ol> + <li><b>Processos em primeiro plano</b> + <p>Um processo necessário para o que o usuário está fazendo. Considera-se + um processo como em primeiro plano se qualquer uma das condições for verdadeira:</p> + + <ul> + <li>Se ele hospedar uma {@link android.app.Activity} com a qual o usuário esteja interagindo (se o método {@link android.app.Activity#onResume onResume()} de {@link +android.app.Activity} +for chamado).</li> + + <li>Se ele hospedar um {@link android.app.Service} vinculado à atividade com a qual o usuário +esteja interagindo.</li> + + <li>Se ele hospedar um {@link android.app.Service} em execução "em primeiro plano"— se o serviço +tiver chamado {@link android.app.Service#startForeground startForeground()}. + + <li>Se ele hospedar um {@link android.app.Service} que esteja executando um de seus retornos de chamada +do ciclo de vida ({@link android.app.Service#onCreate onCreate()}, {@link android.app.Service#onStart +onStart()}, ou {@link android.app.Service#onDestroy onDestroy()}).</li> + + <li>Se ele hospedar um {@link android.content.BroadcastReceiver} que esteja executando seu método {@link + android.content.BroadcastReceiver#onReceive onReceive()}.</li> + </ul> + + <p>Geralmente, somente poucos processos em primeiro plano existem em um determinado momento. Eles serão eliminados +somente como último recurso — se a memória estiver baixa demais para suportar a execução de todos. Geralmente, neste ponto, +o dispositivo atingiu o estado de paginação de memória. Portanto, eliminar alguns processos em primeiro plano +é necessário para que a interface permaneça responsiva.</p></li> + + <li><b>Processos visíveis</b> + <p>Um processo que não tenha nenhum componente em primeiro plano, + mas que ainda possa afetar o que o usuário vê na tela. Um processo é considerado visível + se uma das condições a seguir for verdadeira:</p> + + <ul> + <li>Se ele hospedar um {@link android.app.Activity} que não esteja em primeiro plano, +mas ainda seja visível para o usuário (o seu método {@link android.app.Activity#onPause onPause()} tiver sido chamado). +Isto poderá ocorrer, por exemplo, se a atividade em primeiro plano iniciar um diálogo, o que permitirá +que a atividade anterior seja vista por trás dela.</li> + + <li>Se ele hospedar um {@link android.app.Service} que esteja vinculado a uma atividade visível +(ou em primeiro plano).</li> + </ul> + + <p>Um processo visível é considerado extremamente importante e não será eliminado a não ser +que seja necessário para manter em execução os processos em primeiro plano. </p> + </li> + + <li><b>Processos de serviço</b> + <p>Um processo que esteja executando um serviço que tenha sido iniciado com o método {@link +android.content.Context#startService startService()} e não +esteja em uma das duas categorias mais altas. Apesar de processos de serviço não estarem diretamente ligados a tudo o que os usuários veem, +eles estão geralmente fazendo coisas com que o usuário se importa (como reproduzindo música em segundo plano +ou baixando dados na rede), então o sistema os mantém em execução a não ser que haja memória suficiente +para retê-los juntamente com todos os processos visíveis e em primeiro plano. </p> + </li> + + <li><b>Processos em segundo plano</b> + <p>Um processo que mantenha uma atividade que não esteja atualmente visível para o usuário (se o método +{@link android.app.Activity#onStop onStop()} da atividade tiver sido chamado). Esses processos não têm impacto direto +na experiência do usuário e o sistema poderá eliminá-los a qualquer momento para recuperar memória para processos +em primeiro plano, +visíveis ou de serviço. Geralmente há vários processos em segundo plano em execução e eles são mantidos +em uma lista LRU (least recently used - menos usados recentemente) para garantir que o processo com a atividade +que foi mais vista recentemente pelo usuário seja a última a ser eliminada. Se uma atividade implementar o seu método de ciclo de vida +corretamente e salvar o estado atual, eliminar o seu processo não terá efeito visível +na experiência do usuário, pois quando ele navegar de volta à atividade, ela restaurará +todo o estado visível. Consulte o documento <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Atividades</a> +para obter informações sobre os estados de restauração e de gravação.</p> + </li> + + <li><b>Processos vazios</b> + <p>Um processo que não possui nenhum componente de aplicativo ativo. O único motivo para manter este tipo de processo +ativo é para armazenamento em cache, para aprimorar o tempo de inicialização +na próxima vez em que um componente precisar executá-lo. O sistema frequentemente elimina esses processos para equilibrar os recursos do sistema em geral +entre os armazenamentos em cache do processo e os de núcleo subjacente.</p> + </li> +</ol> + + + <p>O Android coloca o processo no maior nível possível, com base na importância dos componentes +atualmente ativos no processo. Por exemplo, se um processo hospedar um serviço e uma atividade visível +, ele terá a classificação de um processo visível, e não a de um processo de serviço.</p> + + <p>Além disso, a classificação de um processo pode ser elevada porque outros processos +dependem dele — um processo que está servindo a outro processo nunca pode ter classificação menor +do que a do processo que está sendo servido. Por exemplo, se um provedor de conteúdo no processo A estiver servindo um cliente no processo B, +ou se um serviço no processo A estiver vinculado a um componente no processo B, o processo A será sempre considerado +menos importante do que o processo B.</p> + + <p>Como um processo que executa um serviço tem classificação maior do que um processo com atividades em segundo plano, +uma atividade que iniciar uma operação de longo prazo poderá também iniciar um <a href="{@docRoot}guide/components/services.html">serviço</a> para esta operação, em vez de simplesmente +criar um encadeamento de trabalho — especificamente se a operação exceder a atividade. +Por exemplo, uma atividade que esteja fazendo upload de uma imagem para um site deverá iniciar um serviço +para fazer o upload para que ele possa continuar em segundo plano mesmo se o usuário deixar a atividade. +Usar um serviço garante que a operação tenha pelo menos a prioridade "processo de serviço", +independente do que acontecer à atividade. Este é o mesmo motivo pelo qual os receptores de transmissão devem +empregar serviços em vez de simplesmente usar operações que consomem tempo em um encadeamento.</p> + + + + +<h2 id="Threads">Encadeamentos</h2> + +<p>Quando um aplicativo é executado, o sistema cria um encadeamento de execução para ele, +chamado de "principal". Este encadeamento é muito importante, pois está encarregado de despachar eventos +para os widgets adequados da interface do usuário, incluindo eventos de desenho. É também o encadeamento +em que o aplicativo interage com componentes do kit de ferramentas da IU do Android (componentes dos pacotes {@link +android.widget} e {@link android.view}). Portanto, o encadeamento principal, às vezes, +também chama o encadeamento da IU.</p> + +<p>O sistema <em>não</em> cria um encadeamento separado para cada instância de um componente. Todos os componentes +executados no mesmo processo são instanciados no encadeamento da IU, e as chamadas do sistema +para cada componente são despachadas deste encadeamento. Consequentemente, métodos que respondam aos retornos de chamada +(como {@link android.view.View#onKeyDown onKeyDown()} para informar ações de usuário +ou um método de retorno de chamada do ciclo de vida) sempre serão executados no encadeamento da IU do processo.</p> + +<p>Por exemplo, quando o usuário toca em um botão na tela, o encadeamento da IU do aplicativo despacha +o evento de toque para o widget que, em troca, ativa o seu estado pressionado e publica uma solicitação de invalidação +à fila do evento. O encadeamento da IU retira a solicitação da fila e notifica o widget de que ele deve +desenhar novamente por conta própria.</p> + +<p>Quando o aplicativo realiza trabalho intenso em resposta à interação do usuário, este modelo de único encadeamento +pode produzir desempenho inferior a não ser que você implemente o aplicativo adequadamente. Especificamente, se tudo estiver +acontecendo no encadeamento da IU, realizar operações longas, como acesso à rede +ou consultas a banco de dados, bloqueará toda a IU. Quando o encadeamento é bloqueado, nenhum evento pode ser despachado, +incluindo eventos de desenho. Da perspectiva do usuário, +o aplicativo parece travar. Pior ainda, se o encadeamento da IU for bloqueado por mais do que alguns segundos +(cerca de 5 segundos atualmente), o usuário receberá a vergonhosa mensagem "<a href="http://developer.android.com/guide/practices/responsiveness.html">aplicativo +não respondendo</a>" (ANR). O usuário poderá, então, decidir fechar o aplicativo e desinstalá-lo +se estiver descontente.</p> + +<p>Além disso, o kit de ferramentas de IU do Android <em>não</em> é seguro para encadeamentos. Portanto, você não deve manipular a IU +a partir de um encadeamento de trabalho — deve-se realizar toda a manipulação para a interface do usuário +a partir do encadeamento da IU. Com isso dito, há duas regras simples para o modelo de encadeamento único do Android:</p> + +<ol> +<li>Não bloquear o encadeamento da IU +<li>Não acessar o kit de ferramentas de IU do Android fora do encadeamento da IU +</ol> + +<h3 id="WorkerThreads">Encadeamentos de trabalho</h3> + +<p>Por causa do modelo de encadeamento único descrito acima, é essencial para a capacidade de resposta da IU do aplicativo +que você não bloqueie o encadeamento da IU. Caso tenha operações a realizar +que não sejam instantâneas, deverá certificar-se de fazê-las em encadeamentos separados (encadeamentos de "segundo plano" +ou "de trabalho").</p> + +<p>Por exemplo, abaixo apresenta-se o código de uma escuta de clique que baixa uma imagem de um encadeamento separado +e exibe-a em uma {@link android.widget.ImageView}:</p> + +<pre> +public void onClick(View v) { + new Thread(new Runnable() { + public void run() { + Bitmap b = loadImageFromNetwork("http://example.com/image.png"); + mImageView.setImageBitmap(b); + } + }).start(); +} +</pre> + +<p>À primeira vista, parece não apresentar problemas, pois ele cria um novo encadeamento para lidar +com a operação de rede. No entanto, ele viola a segunda regra do modelo de encadeamento único: <em>não acessar o kit de ferramentas de IU do Android +de fora do encadeamento da IU</em> — este exemplo modifica o {@link +android.widget.ImageView} a partir do encadeamento de trabalho em vez de o encadeamento da IU. Isto pode resultar em comportamentos +inesperados e indefinidos, que podem ser difíceis de rastrear e consumir bastante tempo.</p> + +<p>Para resolver este problema, o Android oferece várias maneiras de acessar o encadeamento da IU a partir +de outros encadeamentos. Abaixo há uma lista dos métodos que podem ajudar:</p> + +<ul> +<li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable) +Activity.runOnUiThread(Runnable)}</li> +<li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li> +<li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable, +long)}</li> +</ul> + +<p>Por exemplo, é possível resolver o código acima usando o método {@link +android.view.View#post(java.lang.Runnable) View.post(Runnable)}:</p> + +<pre> +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(); +} +</pre> + +<p>Agora esta implementação é segura para encadeamentos: a operação de rede é concluída a partir de um encadeamento separado +enquanto que a {@link android.widget.ImageView} é manipulada a partir do encadeamento da IU.</p> + +<p>No entanto, à medida que a complexidade da operação aumenta, este tipo de código pode tornar-se complexo +e difícil demais para ser mantido. Para lidar com interações mais complexas com um encadeamento de trabalho, considere +usar um {@link android.os.Handler} nele para processar as mensagens entregues +pelo encadeamento da IU. Apesar de que, talvez, a melhor solução seja estender a classe {@link android.os.AsyncTask}, +que simplifica a execução das tarefas do encadeamento de trabalho que precisam interagir com a IU.</p> + + +<h4 id="AsyncTask">Uso de AsyncTask</h4> + +<p>{@link android.os.AsyncTask} permite que você trabalhe de forma assíncrona +na interface do usuário. Ela realiza operações de bloqueio em um encadeamento de trabalho e, em seguida, publica os resultados +no encadeamento da IU, sem que você precise lidar com os encadeamentos e/ou os manipuladores.</p> + +<p>Para usá-la, você deve atribuir a subclasse {@link android.os.AsyncTask} e implementar o método de retorno de chamada {@link +android.os.AsyncTask#doInBackground doInBackground()}, que executa uma série +de encadeamentos de segundo plano. Para atualizar a IU, deve-se implementar {@link +android.os.AsyncTask#onPostExecute onPostExecute()}, que entrega o resultado de {@link +android.os.AsyncTask#doInBackground doInBackground()} e é executado no encadeamento da IU para que seja possível +atualizar a IU de forma segura. É possível, em seguida, executar a tarefa chamando {@link android.os.AsyncTask#execute execute()} +a partir do encadeamento da IU.</p> + +<p>Por exemplo, é possível implementar o exemplo anterior usando {@link android.os.AsyncTask} +da seguinte forma:</p> + +<pre> +public void onClick(View v) { + new DownloadImageTask().execute("http://example.com/image.png"); +} + +private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { + /** The system calls this to perform work in a worker thread and + * delivers it the parameters given to AsyncTask.execute() */ + protected Bitmap doInBackground(String... urls) { + return loadImageFromNetwork(urls[0]); + } + + /** The system calls this to perform work in the UI thread and delivers + * the result from doInBackground() */ + protected void onPostExecute(Bitmap result) { + mImageView.setImageBitmap(result); + } +} +</pre> + +<p>Agora a IU está segura e o código está mais simples, pois ele separa o trabalho +em uma parte que deve ser feita em um encadeamento de trabalho e outra parte que deve ser feita no encadeamento da IU.</p> + +<p>Leia a referência {@link android.os.AsyncTask} para compreender melhor +o uso desta classe, mas a seguir há uma visão geral rápida sobre como ela funciona:</p> + +<ul> +<li>É possível especificar o tipo dos parâmetros, valores de progresso e valor final +da tarefa, usando genéricos</li> +<li>O método {@link android.os.AsyncTask#doInBackground doInBackground()} é executado automaticamente +em um encadeamento de trabalho</li> +<li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}, {@link +android.os.AsyncTask#onPostExecute onPostExecute()} e {@link +android.os.AsyncTask#onProgressUpdate onProgressUpdate()} são invocados no encadeamento da IU</li> +<li>O valor retornado por {@link android.os.AsyncTask#doInBackground doInBackground()} +é enviado para {@link android.os.AsyncTask#onPostExecute onPostExecute()}</li> +<li>É possível chamar {@link android.os.AsyncTask#publishProgress publishProgress()} a qualquer momento em {@link +android.os.AsyncTask#doInBackground doInBackground()} para executar {@link +android.os.AsyncTask#onProgressUpdate onProgressUpdate()} no encadeamento da IU</li> +<li>É possível cancelar a tarefa a qualquer momento, a partir de qualquer encadeamento</li> +</ul> + +<p class="caution"><strong>Atenção:</strong> outro problema que pode ocorrer ao usar +um encadeamento de trabalho são reinicializações inesperadas da atividade devido a <a href="{@docRoot}guide/topics/resources/runtime-changes.html">alterações na configuração em tempo de execução</a> +(como quando o usuário altera a orientação da tela), que podem eliminar o encadeamento de trabalho. Para ver como é possível +manter uma tarefa durante uma dessas reinicializações e como cancelar adequadamente a tarefa +quando a atividade for eliminada, consulte o código fonte do aplicativo <a href="http://code.google.com/p/shelves/">Prateleiras</a> de exemplo.</p> + + +<h3 id="ThreadSafe">Métodos seguros de encadeamento</h3> + +<p> Em algumas situações, os métodos implementados podem ser chamados a partir de mais de um encadeamento e, portanto, +devem ser programados para serem seguros para encadeamento. </p> + +<p>Isto é especialmente verdadeiro para métodos que podem ser cancelados remotamente — como métodos em um <a href="{@docRoot}guide/components/bound-services.html">serviço vinculado</a>. Quando uma chamada +de um método implementado em um {@link android.os.IBinder} tiver origem no mesmo processo +em que {@link android.os.IBinder IBinder} estiver em execução, o método será executado no encadeamento do autor da chamada. +No entanto, quando a chamada tiver origem em outro processo, o método será executado em um encadeamento +escolhido a partir de uma série de encadeamentos que o sistema mantém no mesmo processo que {@link android.os.IBinder +IBinder} (ele não será executado no encadeamento da IU do processo). Por exemplo, enquanto o método +{@link android.app.Service#onBind onBind()} de um serviço seria chamado a partir de um encadeamento da IU do processo +de um serviço, os métodos implementados no objeto que {@link android.app.Service#onBind +onBind()} retorna (por exemplo, uma subclasse que implementa métodos de RPC) seriam chamados +a partir dos encadeamentos no conjunto. Como um serviço pode ter mais de um cliente, mais de um encadeamento no conjunto +pode envolver o mesmo método {@link android.os.IBinder IBinder} ao mesmo tempo. Os métodos {@link android.os.IBinder +IBinder} devem, portanto, ser implementados para serem seguros para encadeamentos.</p> + +<p> De forma semelhante, um provedor de conteúdo pode receber solicitações de dados que tenham origem em outros processos. +Apesar de as classes {@link android.content.ContentResolver} e {@link android.content.ContentProvider} +ocultarem os detalhes de como a comunicação entre processos é gerenciada, os métodos {@link +android.content.ContentProvider} que respondem a essas solicitações — os métodos {@link +android.content.ContentProvider#query query()}, {@link android.content.ContentProvider#insert +insert()}, {@link android.content.ContentProvider#delete delete()}, {@link +android.content.ContentProvider#update update()} e {@link android.content.ContentProvider#getType +getType()} — serão chamados de um conjunto de encadeamentos no processo do provedor de conteúdo, não no encadeamento da IU +para o processo. Como esses métodos podem ser chamados a partir de qualquer quantidade de encadeamentos +ao mesmo tempo, eles também devem ser implementados para serem seguros para encadeamento. </p> + + +<h2 id="IPC">Comunicação entre processos</h2> + +<p>O Android oferece um mecanismo para comunicação entre processos (IPC) usando chamadas de procedimento remoto (RPCs), +onde um método é chamado por uma atividade ou outro componente de aplicativo, mas é executado +remotamente (em outro processo), com qualquer resultado retornado +de volta ao autor da chamada. Isto acarreta na decomposição de uma chamada de método e de seus dados para um nível em que o sistema operacional +possa entender, transmitindo-a do processo local e do espaço de endereço ao processo remoto +e ao espaço de endereço e, em seguida, remontando e restabelecendo a chamada lá. Os valores de retorno +são transmitidos na direção oposta. O Android fornece todo o código para realizar essas operações +de IPC para que você possa concentrar-se em definir e implementar a interface de programação de RPC. </p> + +<p>Para realizar o IPC, o aplicativo deve vincular-se a um serviço usando {@link +android.content.Context#bindService bindService()}. Para obter mais informações, consulte o guia do desenvolvedor <a href="{@docRoot}guide/components/services.html">Serviços</a>.</p> + + +<!-- +<h2>Beginner's Path</h2> + +<p>For information about how to perform work in the background for an indefinite period of time +(without a user interface), continue with the <b><a +href="{@docRoot}guide/components/services.html">Services</a></b> document.</p> +--> diff --git a/docs/html-intl/intl/pt-br/guide/components/recents.jd b/docs/html-intl/intl/pt-br/guide/components/recents.jd new file mode 100644 index 000000000000..467f62067a54 --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/recents.jd @@ -0,0 +1,256 @@ +page.title=Tela de visão geral +page.tags="recents","overview" + +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + + <h2>Neste documento</h2> + <ol> + <li><a href="#adding">Adição de tarefas à tela de visão geral</a> + <ol> + <li><a href="#flag-new-doc">Uso do sinalizador Intent para adicionar uma tarefa</a></li> + <li><a href="#attr-doclaunch">Uso do atributo Activity para adicionar uma tarefa</a></li> + </ol> + </li> + <li><a href="#removing">Remoção de tarefas</a> + <ol> + <li><a href="#apptask-remove">Uso da classe AppTask para remover tarefas</a></li> + <li><a href="#retain-finished">Retenção de tarefas terminadas</a></li> + </ol> + </li> + </ol> + + <h2>Classes principais</h2> + <ol> + <li>{@link android.app.ActivityManager.AppTask}</li> + <li>{@link android.content.Intent}</li> + </ol> + + <h2>Exemplo de código</h2> + <ol> + <li><a href="{@docRoot}samples/DocumentCentricApps/index.html">Aplicativos centralizados em documentos</a></li> + </ol> + +</div> +</div> + +<p>A tela de visão geral (também chamada de tela de recentes, lista de tarefas recentes ou aplicativos recentes) +é uma IU de nível de sistema que lista <a href="{@docRoot}guide/components/activities.html"> +atividades</a> e <a href="{@docRoot}guide/components/tasks-and-back-stack.html">tarefas</a> acessadas recentemente. O +usuário pode navegar pela lista e selecionar uma tarefa a retomar ou remover uma tarefa da +lista deslizando-a para fora. Com a versão 5.0 do Android (API de nível 21), várias instâncias da +mesma atividade contendo diferentes documentos podem aparecer como tarefas na tela de visão geral. Por exemplo, o +Google Drive pode ter uma tarefa para cada um dos vários documentos do Google. Cada documento aparece como uma +tarefa na tela de visão geral.</p> + +<img src="{@docRoot}images/components/recents.png" alt="" width="284" /> +<p class="img-caption"><strong>Figura 1.</strong> A tela de visão geral mostrando três documentos do Google Drive, +cada um representado como uma tarefa separada.</p> + +<p>Normalmente, você deve permitir que o sistema defina como as tarefas e as +atividades são representadas na tela de visão geral e não precisa modificar esse comportamento. +No entanto, o seu aplicativo pode determinar como e quando as atividades aparecem na tela de visão geral. A +classe {@link android.app.ActivityManager.AppTask} permite gerenciar tarefas e os sinalizadores de atividade da classe +{@link android.content.Intent} permitem especificar quando uma atividade é adicionada ou removida da +tela de visão geral. Além disso, os atributos <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"> +<activity></a></code> permitem definir o comportamento no manifesto.</p> + +<h2 id="adding">Adição de tarefas à tela de visão geral</h2> + +<p>Usar os sinalizadores da classe {@link android.content.Intent} para adicionar uma tarefa permite maior controle sobre +quando e como um documento é aberto ou reaberto na tela de visão geral. Ao usar os atributos +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>, +é possível escolher entre sempre abrir o documento em uma nova tarefa ou reutilizar uma +tarefa existente para o documento.</p> + +<h3 id="flag-new-doc">Uso do sinalizador Intent para adicionar uma tarefa</h3> + +<p>Ao criar um novo documento para a atividade, você chama o método +{@link android.app.ActivityManager.AppTask#startActivity(android.content.Context, android.content.Intent, android.os.Bundle) startActivity()} +da classe {@link android.app.ActivityManager.AppTask}, passando a ele a intenção que +inicia a atividade. Para inserir uma quebra lógica para que o sistema trate a atividade como uma nova +tarefa na tela de visão geral, passe o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} +no método {@link android.content.Intent#addFlags(int) addFlags()} da {@link android.content.Intent} +que inicia a atividade.</p> + +<p class="note"><strong>Observação:</strong> o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} +substitui o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET}, +obsoleto a partir do Android 5.0 (API de nível 21).</p> + +<p>Se você usar o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} ao criar +o novo documento, o sistema sempre criará uma nova tarefa com a atividade-alvo como raiz. +Essa configuração permite que o mesmo documento seja aberto em mais de uma tarefa. O código a seguir demonstra +como a atividade principal faz isso:</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +DocumentCentricActivity.java</a></p> +<pre> +public void createNewDocument(View view) { + final Intent newDocumentIntent = newDocumentIntent(); + if (useMultipleTasks) { + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); + } + startActivity(newDocumentIntent); + } + + private Intent newDocumentIntent() { + boolean useMultipleTasks = mCheckbox.isChecked(); + final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class); + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); + newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet()); + return newDocumentIntent; + } + + private static int incrementAndGet() { + Log.d(TAG, "incrementAndGet(): " + mDocumentCounter); + return mDocumentCounter++; + } +} +</pre> + +<p class="note"><strong>Observação:</strong> Atividades iniciadas com o sinalizador {@code FLAG_ACTIVITY_NEW_DOCUMENT} +devem ter o valor do atributo {@code android:launchMode="standard"} (o padrão) definido no +manifesto.</p> + +<p>Quando a atividade principal inicia uma nova atividade, o sistema procura nas tarefas existentes uma +cuja intenção corresponda ao nome do componente da intenção e aos dados de Intent para a atividade. Se a tarefa +não for encontrada ou se a intenção continha o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}, +uma nova tarefa será criada com a atividade como raiz. Se o sistema encontrar uma tarefa, ele a trará +para a frente e passará a nova intenção para {@link android.app.Activity#onNewIntent onNewIntent()}. +A nova atividade receberá a intenção e criará um novo documento na tela de visão geral, como no +exemplo a seguir:</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +NewDocumentActivity.java</a></p> +<pre> +@Override +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_new_document); + mDocumentCount = getIntent() + .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0); + mDocumentCounterTextView = (TextView) findViewById( + R.id.hello_new_document_text_view); + setDocumentCounterText(R.string.hello_new_document_counter); +} + +@Override +protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity + is reused to create a new document. + */ + setDocumentCounterText(R.string.reusing_document_counter); +} +</pre> + + +<h3 id="#attr-doclaunch">Uso do atributo Activity para adicionar uma tarefa</h3> + +<p>Uma atividade também pode especificar em seu manifesto que sempre iniciará uma nova tarefa usando +o atributo <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>, + <a href="{@docRoot}guide/topics/manifest/activity-element.html#dlmode"> +{@code android:documentLaunchMode}</a>. Esse atributo tem quatro valores que produzem os seguintes +efeitos quando o usuário abre um documento com o aplicativo:</p> + +<dl> + <dt>"{@code intoExisting}"</dt> + <dd>A atividade reutiliza uma tarefa existente para o documento. Isso é o mesmo que configurar o + sinalizador {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} <em>sem</em> configurar + o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}, como descrito em + <a href="#flag-new-doc">Uso do sinalizador Intent para adicionar uma tarefa</a> acima.</dd> + + <dt>"{@code always}"</dt> + <dd>A atividade cria uma nova tarefa para o documento, mesmo se o mesmo já estiver aberto. Usar + esse valor é o mesmo que configurar os sinalizadores {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} + e {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}.</dd> + + <dt>"{@code none”}"</dt> + <dd>A atividade não cria uma nova tarefa para o documento. A tela de visão geral trata a + atividade como aconteceria por padrão: ela exibe uma tarefa para o aplicativo, que + retoma a atividade invocada por último pelo usuário.</dd> + + <dt>"{@code never}"</dt> + <dd>A atividade não cria uma nova tarefa para o documento. Definir esse valor substitui o + comportamento dos sinalizadores {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} + e {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}, caso um deles esteja definido + na intenção, e a tela de visão geral exibe uma tarefa para o aplicativo, que retoma a + atividade invocada por último pelo usuário.</dd> +</dl> + +<p class="note"><strong>Observação:</strong> para valores diferentes de {@code none} e {@code never}, a +atividade deve ser definida com {@code launchMode="standard"}. Se esse atributo não for especificado, +{@code documentLaunchMode="none"} será usado.</p> + +<h2 id="removing">Remoção de tarefas</h2> + +<p>Por padrão, uma tarefa de documento é automaticamente removida da tela de visão geral quando a atividade +termina. Esse comportamento pode ser substituído com a classe {@link android.app.ActivityManager.AppTask}, +com um sinalizador {@link android.content.Intent} ou com um atributo <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"> +<activity></a></code>.</p> + +<p>É possível excluir inteiramente uma tarefa da tela de visão geral definindo o +atributo <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>, + <a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude"> +{@code android:excludeFromRecents}</a> como {@code true}.</p> + +<p>É possível definir o número máximo de tarefas que o aplicativo pode incluir na tela de visão geral definindo +o atributo <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +<a href="{@docRoot}guide/topics/manifest/activity-element.html#maxrecents">{@code android:maxRecents} +</a> como um valor inteiro. O padrão é 16. Quando o número máximo de tarefas é atingido, a tarefa usada menos +recentemente é removida da tela de visão geral. O valor máximo de {@code android:maxRecents} +é 50 (25 em dispositivos com pouca memória); valores menores que 1 não são válidos.</p> + +<h3 id="#apptask-remove">Uso da classe AppTask para remover tarefas</h3> + +<p>Na atividade que cria uma nova tarefa na tela de visão geral, é possível +especificar quando remover a tarefa e terminar todas as atividades associadas a ela chamando +o método {@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()}.</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +NewDocumentActivity.java</a></p> +<pre> +public void onRemoveFromRecents(View view) { + // The document is no longer needed; remove its task. + finishAndRemoveTask(); +} +</pre> + +<p class="note"><strong>Observação:</strong> o uso +do método {@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()} +substitui o uso do sinalizador {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} +discutido abaixo.</p> + +<h3 id="#retain-finished">Retenção de tarefas terminadas</h3> + +<p>Se você deseja reter uma tarefa na tela de visão geral, mesmo que a atividade tenha terminado, passe +o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} no +método {@link android.content.Intent#addFlags(int) addFlags()} da Intent que inicia a atividade.</p> + +<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html"> +DocumentCentricActivity.java</a></p> +<pre> +private Intent newDocumentIntent() { + final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class); + newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | + android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); + newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet()); + return newDocumentIntent; +} +</pre> + +<p>Para obter o mesmo efeito, defina o +atributo <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +<a href="{@docRoot}guide/topics/manifest/activity-element.html#autoremrecents"> +{@code android:autoRemoveFromRecents}</a> como {@code false}. O valor padrão é {@code true} +para atividades de documentos e {@code false} para atividades comuns. Usar esse atributo substitui +o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} discutido anteriormente.</p> + + + + + + + diff --git a/docs/html-intl/intl/pt-br/guide/components/services.jd b/docs/html-intl/intl/pt-br/guide/components/services.jd new file mode 100644 index 000000000000..123d90ac9cb3 --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/services.jd @@ -0,0 +1,813 @@ +page.title=Serviços +@jd:body + +<div id="qv-wrapper"> +<ol id="qv"> +<h2>Neste documento</h2> +<ol> +<li><a href="#Basics">Conceitos básicos</a></li> +<ol> + <li><a href="#Declaring">Declaração de serviço no manifesto</a></li> +</ol> +<li><a href="#CreatingAService">Criação de serviço iniciado</a> + <ol> + <li><a href="#ExtendingIntentService">Extensão da classe IntentService</a></li> + <li><a href="#ExtendingService">Extensão da classe Service</a></li> + <li><a href="#StartingAService">Início de serviço</a></li> + <li><a href="#Stopping">Interrupção de serviço</a></li> + </ol> +</li> +<li><a href="#CreatingBoundService">Criação de serviço vinculado</a></li> +<li><a href="#Notifications">Envio de notificações ao usuário</a></li> +<li><a href="#Foreground">Execução de serviço em primeiro plano</a></li> +<li><a href="#Lifecycle">Gerenciamento do ciclo de vida de um serviço</a> +<ol> + <li><a href="#LifecycleCallbacks">Implementação dos retornos de chamada do ciclo de vida</a></li> +</ol> +</li> +</ol> + +<h2>Classes principais</h2> +<ol> + <li>{@link android.app.Service}</li> + <li>{@link android.app.IntentService}</li> +</ol> + +<h2>Exemplos</h2> +<ol> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code + ServiceStartArguments}</a></li> + <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code + LocalService}</a></li> +</ol> + +<h2>Veja também</h2> +<ol> +<li><a href="{@docRoot}guide/components/bound-services.html">Serviços vinculados</a></li> +</ol> + +</div> + + +<p>Um {@link android.app.Service} é um componente do aplicativo que pode realizar +operações longas e não fornece uma interface do usuário. Outro componente do aplicativo +pode iniciar um serviço e ele continuará em execução em segundo plano mesmo que o usuário +alterne para outro aplicativo. Além disso, um componente poderá vincular-se a um serviço +para interagir com ele e até estabelecer comunicação entre processos (IPC). Por exemplo, um serviço pode lidar +com operações de rede, reproduzir música, executar E/S de arquivos, ou interagir com um provedor de conteúdo, +tudo a partir do segundo plano.</p> + +<p>Um serviço pode essencialmente ter duas formas:</p> + +<dl> + <dt>Iniciado</dt> + <dd>Um serviço é "iniciado" quando um componente do aplicativo (como um atividade) +inicia-o chamando {@link android.content.Context#startService startService()}. Quando iniciado, um serviço +pode ficar em execução em segundo plano indefinidamente, mesmo que o componente que o iniciou seja destruído. Geralmente, +um serviço iniciado realiza uma única operação e não retorna um resultado para o autor da chamada. +Por exemplo, ele pode fazer download ou upload de um arquivo pela rede. Quando a operação for concluída, +o serviço deverá ser interrompido.</dd> + <dt>Vinculado</dt> + <dd>Um serviço é "vinculado" quando um componente do aplicativo o vincula chamando {@link +android.content.Context#bindService bindService()}. Um serviço vinculado oferece uma interface +servidor-cliente que permite que os componentes interajam com a interface, enviem solicitações, obtenham resultados, +mesmo em processos com comunicação interprocessual (IPC). Um serviço vinculado permanece em execução somente enquanto +outro componente do aplicativo estiver vinculado a ele. Vários componentes podem ser vinculados ao serviço de uma só vez, +mas quando todos desfizerem o vínculo, o serviço será destruído.</dd> +</dl> + +<p>Apesar de esta documentação discutir os dois tipos de serviços separadamente, +um serviço pode funcionar das duas maneiras — ele pode ser iniciado (para permanecer em execução indefinidamente) e também permitir a vinculação. +Basta você implementar alguns métodos de retorno de chamada: {@link +android.app.Service#onStartCommand onStartCommand()} para permitir que os componentes iniciem o serviço e {@link +android.app.Service#onBind onBind()} para permitir a vinculação.</p> + +<p>Se o aplicativo for iniciado, vinculado ou ambos, qualquer componente do aplicativo +poderá usar o serviço (mesmo a partir de um aplicativo separado), da mesma forma que qualquer componente poderá usar +uma atividade — iniciando com uma {@link android.content.Intent}. No entanto, é possível declarar +o serviço como privado, no arquivo do manifesto, e bloquear o acesso de outros aplicativos. Isto é discutido com mais detalhes +na seção <a href="#Declaring">Declaração do serviço +no manifesto</a>.</p> + +<p class="caution"><strong>Atenção:</strong> um serviço é executado +no encadeamento principal em seu processo de hospedagem — o serviço <strong>não</strong> cria seu próprio encadeamento +e <strong>não</strong> é executado em um processo separado (salvo se especificado). Isso significa que, + se o serviço for realizar qualquer trabalho intensivo de CPU ou operações de bloqueio (como reprodução +de MP3 ou rede), você deve criar um novo encadeamento dentro do serviço. Usando um encadeamento separado, +você reduzirá o risco da ocorrência de erros de Aplicativo não respondendo (ANR) +e o encadeamento principal do aplicativo poderá permanecer dedicado à interação do usuário com as atividades.</p> + + +<h2 id="Basics">Conceitos básicos</h2> + +<div class="sidebox-wrapper"> +<div class="sidebox"> + <h3>Você deve usar um serviço ou um encadeamento?</h3> + <p>Um serviço é simplesmente um componente que pode ser executado em segundo plano mesmo quando o usuário +não está interagindo com o aplicativo. Portanto, um serviço deve ser criado somente +se for realmente necessário.</p> + <p>Caso precise realizar trabalhos fora do encadeamento principal, mas somente enquanto o usuário estiver interagindo +com o aplicativo, então você deve criar um novo encadeamento e não um serviço. Por exemplo, +se quiser reproduzir músicas, mas somente enquanto a atividade estiver em execução, você pode criar um encadeamento +em {@link android.app.Activity#onCreate onCreate()}, iniciando a execução em {@link +android.app.Activity#onStart onStart()}, e interrompendo em {@link android.app.Activity#onStop +onStop()}. Considere também usar {@link android.os.AsyncTask} ou {@link android.os.HandlerThread}, +em vez de a classe tradicional {@link java.lang.Thread}. Consulte o documento <a href="{@docRoot}guide/components/processes-and-threads.html#Threads">Processos e +encadeamentos</a> para obter mais informações sobre encadeamentos.</p> + <p>Lembre-se de que, se usar um serviço, ele ainda será executado no encadeamento principal do aplicativo por padrão, +portanto deve-se criar um novo encadeamento dentro do serviço se ele realizar operações +intensivas ou de bloqueio.</p> +</div> +</div> + +<p>Para criar um serviço, você deve criar uma subclasse de {@link android.app.Service} +(ou uma das subclasses existentes). Na implementação, será necessário substituir alguns métodos de retorno de chamada +que lidem com aspectos essenciais do ciclo de vida do serviço e forneçam um mecanismo para vincular +componentes ao serviço, se apropriado. Os dois métodos mais importantes de retorno de chamada que você deve substituir são:</p> + +<dl> + <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt> + <dd>O sistema chama este método quando outro componente, como uma atividade, +solicita que o serviço seja iniciado, chamando {@link android.content.Context#startService +startService()}. Quando este método é executado, o serviço é iniciado e pode ser executado +em segundo plano indefinidamente. Se implementar isto, é de sua responsabilidade interromper o serviço +quando o trabalho for concluído, chamando {@link android.app.Service#stopSelf stopSelf()} ou {@link +android.content.Context#stopService stopService()} (caso queira somente fornecer a vinculação, +não é necessário implementar este método).</dd> + <dt>{@link android.app.Service#onBind onBind()}</dt> + <dd>O sistema chama este método quando outro componente quer vincular-se +ao serviço (como para realizações de RPC) chamando {@link android.content.Context#bindService +bindService()}. Na implementação deste método, você deve fornecer uma interface que os clientes +usem para comunicar-se com o serviço, retornando um {@link android.os.IBinder}. Você sempre deve implementar este método, +mas, se não quiser permitir a vinculação, retorne nulo.</dd> + <dt>{@link android.app.Service#onCreate()}</dt> + <dd>O sistema chama este método quando o serviço é criado pela primeira vez para realizar procedimentos únicos +de configuração (antes de chamar {@link android.app.Service#onStartCommand onStartCommand()} ou +{@link android.app.Service#onBind onBind()}). Se o serviço já estiver em execução, este método +não é chamado.</dd> + <dt>{@link android.app.Service#onDestroy()}</dt> + <dd>O sistema chama este método quando o serviço não é mais usado e está sendo destruído. +O serviço deve implementar isto para limpar quaisquer recursos, como encadeamentos, escutas +registradas, receptores etc. Esta é a última chamada que o serviço recebe.</dd> +</dl> + +<p>Se um componente iniciar o serviço chamando {@link +android.content.Context#startService startService()} (o que resulta em uma chamada para {@link +android.app.Service#onStartCommand onStartCommand()}), +o serviço permanecerá em execução até ser interrompido por conta própria com {@link android.app.Service#stopSelf()} ou por outro componente +chamando {@link android.content.Context#stopService stopService()}.</p> + +<p>Se um componente +chamar {@link android.content.Context#bindService bindService()} para criar o serviço (e {@link +android.app.Service#onStartCommand onStartCommand()} <em>não</em> for chamado), o serviço será executado +somente enquanto o componente estiver vinculado a ele. Quando o serviço for desvinculado de todos os clientes, +o sistema o destruirá.</p> + +<p>O sistema Android forçará a interrupção de um serviço somente quando a memória estiver baixa e precisar +recuperar os recursos do sistema para a atividade com que o usuário estiver interagindo. Se o serviço estiver vinculado a uma atividade que o usuário +tenha atribuído foco, é menos provável que ele seja eliminado. E, se o serviço for declarado para <a href="#Foreground">ser executado em primeiro plano</a> (discutido posteriormente), então ele quase nunca será eliminado. +Caso contrário, se o serviço for iniciado e estiver em uma longa execução, o sistema reduzirá sua posição +na lista de tarefas de segundo plano no decorrer do tempo e o serviço se tornará altamente suscetível +à eliminação — se o serviço for iniciado, então você deve programá-lo para lidar +com reinicializações pelo sistema. Se o sistema eliminar o seu serviço, ele reiniciará assim que os recursos +estiverem disponíveis novamente (apesar de isto também depender do valor que você retornar de {@link +android.app.Service#onStartCommand onStartCommand()}, como discutido a seguir). Para obter mais informações sobre +quando o sistema deve destruir um serviço, consulte o documento <a href="{@docRoot}guide/components/processes-and-threads.html">Processos e encadeamentos</a> +.</p> + +<p>Nas seguintes seções, você verá como é possível criar cada tipo de serviço e como +usá-los a partir de outros componentes do aplicativo.</p> + + + +<h3 id="Declaring">Declaração de serviço no manifesto</h3> + +<p>Como atividades (e outros componentes), você deve declarar todos os serviços no arquivo de manifesto +do aplicativo.</p> + +<p>Para declarar o serviço, adicione um elemento <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> +como filho do elemento <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a> +. Por exemplo:</p> + +<pre> +<manifest ... > + ... + <application ... > + <service android:name=".ExampleService" /> + ... + </application> +</manifest> +</pre> + +<p>Consulte a referência de elemento <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> +para obter mais informações sobre como declarar o serviço no manifesto.</p> + +<p>É possível incluir outros atributos no elemento <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code <service>}</a> +para definir propriedades como permissões necessárias para iniciar o serviço e o processo +em que o serviço deve ser executado. O atributo <a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a> +é o único necessário — ele especifica o nome da classe do serviço. Ao publicar o aplicativo, + não deve-se alterar-lhe o nome porque, se isso acontecer, há riscos de ocorrência de erros +de código devido à dependência de intenções explícitas para iniciar ou vincular o serviço (leia a publicação do blogue, <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Coisas +que não podem mudar</a>). + +<p>Para garantir a segurança do aplicativo, <strong>sempre use uma intenção explícita ao iniciar ou vincular +{@link android.app.Service}</strong> e não declare filtros de intenção para o serviço. Caso seja essencial permitir alguma ambiguidade, como qual serviço deve ser usado para iniciar, +é possível fornecer filtros de intenções +para os serviços e excluir o nome do componente de {@link +android.content.Intent}, mas é preciso definir o pacote para a intenção com {@link +android.content.Intent#setPackage setPackage()}, que fornece desambiguidade suficiente para +o serviço alvo.</p> + +<p>Além disso, é possível garantir que o serviço esteja disponível somente para o aplicativo +incluindo o atributo <a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a> +e definindo-o como {@code "false"}. Isto impede efetivamente que outros aplicativos iniciem o serviço, + mesmo usando uma intenção explícita.</p> + + + + +<h2 id="CreatingStartedService">Criação de um serviço iniciado</h2> + +<p>Um serviço iniciado é o que outro componente inicia chamando {@link +android.content.Context#startService startService()}, resultando em uma chamada para o método +{@link android.app.Service#onStartCommand onStartCommand()} do serviço.</p> + +<p>Quando um serviço é iniciado, ele tem um ciclo de vida que não depende do componente +que o iniciou. Além disso, o serviço pode ser executado em segundo plano indefinidamente, +mesmo se o componente que o iniciou for eliminado. Além disso, o serviço deve ser interrompido quando o seu trabalho +for realizado, chamando {@link android.app.Service#stopSelf stopSelf()}. Outros componentes podem interrompê-lo +chamando {@link android.content.Context#stopService stopService()}.</p> + +<p>Um componente do aplicativo, como uma atividade, pode iniciar o serviço chamando {@link +android.content.Context#startService startService()} e passando {@link android.content.Intent}, +que especifica o serviço e inclui os dados para o serviço usar. O serviço +recebe esta {@link android.content.Intent} no método {@link android.app.Service#onStartCommand +onStartCommand()}.</p> + +<p>Por exemplo, presuma que uma atividade precise salvar alguns dados em um banco de dados on-line. A atividade pode iniciar +um serviço de acompanhamento e entregar a ele os dados a salvar passando uma intenção para {@link +android.content.Context#startService startService()}. O serviço recebe a intenção em {@link +android.app.Service#onStartCommand onStartCommand()}, conecta-se à Internet e realiza +a transação no banco de dados. Quando a operação é concluída, o serviço é interrompido +e destruído.</p> + +<p class="caution"><strong>Atenção:</strong> um serviço é executado no mesmo processo que o aplicativo +em que ele é declarado e no encadeamento principal do aplicativo, por padrão. Portanto, se o serviço +realizar operações intensivas ou de bloqueio quando o usuário interagir com uma atividade do mesmo aplicativo, +diminuirá o desempenho da atividade. Para evitar impacto no desempenho do aplicativo, +deve-se iniciar um novo encadeamento dentro do serviço.</p> + +<p>Geralmente, há duas classes que podem ser estendidas para criar um serviço iniciado:</p> +<dl> + <dt>{@link android.app.Service}</dt> + <dd>Esta é a classe de base para todos os serviços. Ao estender esta classe, é importante +criar um novo encadeamento para fazer todo o trabalho do serviço, pois o serviço usa +o encadeamento principal do aplicativo, por padrão, o que deve diminuir o desempenho de qualquer atividade +que o aplicativo estiver executando.</dd> + <dt>{@link android.app.IntentService}</dt> + <dd>Esta é uma subclasse de {@link android.app.Service} que usa um encadeamento de trabalho para lidar +com todas as solicitações de inicialização, uma por vez. Esta é a melhor opção se não quiser que o serviço +lide com várias solicitações simultaneamente. Tudo que precisa fazer é implementar {@link +android.app.IntentService#onHandleIntent onHandleIntent()}, que recebe a intenção para cada solicitação +de início para que você possa realizar o trabalho de segundo plano.</dd> +</dl> + +<p>As seguintes seções descrevem como é possível implementar o serviço usando +uma dessas classes.</p> + + +<h3 id="ExtendingIntentService">Extensão da classe IntentService</h3> + +<p>Como a maioria dos serviços não precisam lidar com várias solicitações simultaneamente +(o que pode ser perigoso para situações de vários encadeamentos), é melhor +se o serviço for implementado usando a classe {@link android.app.IntentService}.</p> + +<p>O {@link android.app.IntentService} faz o seguinte:</p> + +<ul> + <li>Cria um encadeamento de trabalho padrão que executa todas as intenções entregues a {@link +android.app.Service#onStartCommand onStartCommand()} separado do encadeamento principal +do aplicativo.</li> + <li>Cria uma fila de trabalho que passa uma intenção por vez à implementação {@link +android.app.IntentService#onHandleIntent onHandleIntent()}, para que nunca seja necessário +preocupar-se com vários encadeamentos.</li> + <li>Interrompe o serviço depois que todas as solicitações forem resolvidas para que não seja necessário chamar +{@link android.app.Service#stopSelf}.</li> + <li>Fornece implementações padrão de {@link android.app.IntentService#onBind onBind()} +que retornam como nulo.</li> + <li>Fornece uma implementação padrão de {@link android.app.IntentService#onStartCommand +onStartCommand()} que envia a intenção para a fila de trabalho e, em seguida, para a implementação de {@link +android.app.IntentService#onHandleIntent onHandleIntent()}.</li> +</ul> + +<p>Tudo isso adiciona-se ao fato de que basta implementar {@link +android.app.IntentService#onHandleIntent onHandleIntent()} para fazer o trabalho fornecido +pelo cliente (embora também seja necessário fornecer um pequeno construtor para o serviço).</p> + +<p>A seguir há um exemplo de implementação de {@link android.app.IntentService}:</p> + +<pre> +public class HelloIntentService extends IntentService { + + /** + * A constructor is required, and must call the super {@link android.app.IntentService#IntentService} + * 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) { + } + } + } + } +} +</pre> + +<p>É tudo que você precisa: um construtor e uma implementação de {@link +android.app.IntentService#onHandleIntent onHandleIntent()}.</p> + +<p>Caso decida substituir outros métodos de retorno de chamada, como {@link +android.app.IntentService#onCreate onCreate()}, {@link +android.app.IntentService#onStartCommand onStartCommand()} ou {@link +android.app.IntentService#onDestroy onDestroy()}, certifique-se de chamar a super-implementação +para que o {@link android.app.IntentService} possa lidar adequadamente com a vida do encadeamento de trabalho.</p> + +<p>Por exemplo, {@link android.app.IntentService#onStartCommand onStartCommand()} deve retornar +a implementação padrão (que é como a intenção é entregue para {@link +android.app.IntentService#onHandleIntent onHandleIntent()}):</p> + +<pre> +@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); +} +</pre> + +<p>Além de {@link android.app.IntentService#onHandleIntent onHandleIntent()}, o único método +que não precisa ser usado para chamar a superclasse é {@link android.app.IntentService#onBind +onBind()} (mas é necessário implementá-lo se o serviço permitir vinculações).</p> + +<p>Na próxima seção, você verá como o mesmo tipo de serviço é implementado ao estender +a classe de base {@link android.app.Service}, que possui muito mais códigos, mas que pode +ser apropriada para lidar com solicitações de inicialização simultâneas.</p> + + +<h3 id="ExtendingService">Extensão da classe Service</h3> + +<p>Como você viu na seção anterior, o uso de {@link android.app.IntentService} +torna a implementação de um serviço iniciado muito simples. Se, no entanto, você precisa do serviço +para realizar vários encadeamentos (em vez de processar as solicitações de inicialização por meio de uma fila de trabalho), +é possível estender a classe {@link android.app.Service} para lidar com cada intenção.</p> + +<p>Para efeito de comparação, o seguinte exemplo de código é uma implementação da classe {@link +android.app.Service} que realiza exatamente o mesmo trabalho que o exemplo acima usando {@link +android.app.IntentService}. Ou seja, para cada solicitação de inicialização, ela usa um encadeamento +de trabalho para realizar o trabalho e processa apenas uma solicitação por vez.</p> + +<pre> +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) { + 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; + } + + @Override + public void onDestroy() { + Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); + } +} +</pre> + +<p>Como pode ver, é muito mais trabalhoso do que usar {@link android.app.IntentService}.</p> + +<p>No entanto, como você lida com cada chamada de {@link android.app.Service#onStartCommand +onStartCommand()}, é possível realizar várias solicitações simultaneamente. Isso não é o que este exemplo faz, +mas, se for o que quer, é possível criar um novo encadeamento +para cada solicitação e executá-las na hora (em vez de esperar que a solicitação anterior seja concluída).</p> + +<p>Observe que o método {@link android.app.Service#onStartCommand onStartCommand()} deve retornar +um número inteiro. O número inteiro é um valor que descreve como o sistema deve continuar o serviço +no evento em que o sistema o eliminar (como discutido acima, a implementação padrão de {@link +android.app.IntentService} lida com isto, apesar de ser possível modificá-lo). O valor de retorno +de {@link android.app.Service#onStartCommand onStartCommand()} deve ser uma das seguintes +constantes:</p> + +<dl> + <dt>{@link android.app.Service#START_NOT_STICKY}</dt> + <dd>Se o sistema eliminar o serviço após o retorno de {@link android.app.Service#onStartCommand +onStartCommand()}, <em>não</em> recrie o serviço, a não ser que tenha +intenções pendentes para entregar. Esta é a opção mais segura para evitar executar o serviço quando desnecessário +e quando o aplicativo puder simplesmente reiniciar qualquer trabalho incompleto.</dd> + <dt>{@link android.app.Service#START_STICKY}</dt> + <dd>Se o sistema eliminar o serviço após o retorno de {@link android.app.Service#onStartCommand +onStartCommand()}, recrie o serviço e chame {@link +android.app.Service#onStartCommand onStartCommand()}, mas <em>não</em> entregue novamente a última intenção. +Em vez disso, o sistema chama {@link android.app.Service#onStartCommand onStartCommand()} com intenção nula, +a não ser que tenha intenções pendentes para iniciar o serviço e, +nesse caso, essas intenções são entregues. Isto é adequado para reprodutores de mídia (ou serviços semelhantes) +que não estejam executando comandos, mas estejam em execução indefinidamente e aguardando um trabalho.</dd> + <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt> + <dd>Se o sistema eliminar o serviço após o retorno de {@link android.app.Service#onStartCommand +onStartCommand()}, recrie o serviço e chame {@link +android.app.Service#onStartCommand onStartCommand()} com a última intenção que foi entregue +ao serviço. Quaisquer intenções pendentes são entregues, por sua vez. Isto é adequado para serviços que estejam realizando +um trabalho ativamente que deva ser retomado imediatamente, como o download de um arquivo.</dd> +</dl> +<p>Para obter mais informações sobre esses valores de retorno, veja a documentação de referência vinculada +a cada constante.</p> + + + +<h3 id="StartingAService">Início de um serviço</h3> + +<p>É possível iniciar um dispositivo de uma atividade ou outro componente do aplicativo passando uma +{@link android.content.Intent} a {@link +android.content.Context#startService startService()}. O sistema Android chama o método {@link +android.app.Service#onStartCommand onStartCommand()} do serviço e passa a ele a {@link +android.content.Intent} (nunca deve-se chamar {@link android.app.Service#onStartCommand +onStartCommand()} diretamente).</p> + +<p>Por exemplo, uma atividade pode iniciar o serviço de exemplo na seção anterior ({@code +HelloSevice}) usando uma intenção explícita com {@link android.content.Context#startService +startService()}:</p> + +<pre> +Intent intent = new Intent(this, HelloService.class); +startService(intent); +</pre> + +<p>O método {@link android.content.Context#startService startService()} retorna imediatamente +e o sistema Android chama o método {@link android.app.Service#onStartCommand +onStartCommand()} do serviço. Se o serviço não estiver em execução, o sistemo primeiro chama {@link +android.app.Service#onCreate onCreate()} e, em seguida, chama {@link android.app.Service#onStartCommand +onStartCommand()}.</p> + +<p>Se o serviço não fornecer vinculação, a intenção entregue com {@link +android.content.Context#startService startService()} é o único modo de comunicação entre +o componente do aplicativo e o serviço. No entanto, se quiser que o serviço envie um resultado de volta, +o cliente que iniciar o serviço poderá criar um {@link android.app.PendingIntent} para uma transmissão +(com {@link android.app.PendingIntent#getBroadcast getBroadcast()}) e entregá-la ao serviço +na {@link android.content.Intent} que iniciar o serviço. O serviço pode então +usar a transmissão para entregar um resultado.</p> + +<p>Várias solicitações para iniciar o serviço resultam em diversas chamadas correspondentes +ao {@link android.app.Service#onStartCommand onStartCommand()} do serviço. No entanto, somente uma solicitação para interromper +o serviço (com {@link android.app.Service#stopSelf stopSelf()} ou {@link +android.content.Context#stopService stopService()}) é necessária para interrompê-lo.</p> + + +<h3 id="Stopping">Interrupção de um serviço</h3> + +<p>Um serviço iniciado deve gerenciar seu próprio ciclo de vida. Ou seja, o sistema não interrompe +ou elimina o serviço, a não ser que tenha que recuperar a memória do sistema e o serviço +continuar em execução depois que {@link android.app.Service#onStartCommand onStartCommand()} retornar. Portanto, +o serviço deve ser interrompido chamando {@link android.app.Service#stopSelf stopSelf()} ou outro +componente pode interrompê-lo chamando {@link android.content.Context#stopService stopService()}.</p> + +<p>Ao solicitar o interrompimento com {@link android.app.Service#stopSelf stopSelf()} ou {@link +android.content.Context#stopService stopService()}, o sistema elimina o serviço +assim que possível.</p> + +<p>No entanto, se o serviço lida com várias solicitações para {@link +android.app.Service#onStartCommand onStartCommand()} ao mesmo tempo, não se deve interromper +o serviço ao terminar o processamento de uma solicitação de inicialização, pois é possível +que uma nova solicitação de inicialização tenha ocorrido (interromper no final da primeira solicitação eliminaria a segunda). Para evitar este problema, +é possível usar {@link android.app.Service#stopSelf(int)} para garantir que a solicitação +que interrompe o serviço sempre se baseie na solicitação de inicialização mais recente. Ou seja, ao chamar {@link +android.app.Service#stopSelf(int)}, você passa o ID da solicitação de inicialização (o <code>startId</code> +entregue a {@link android.app.Service#onStartCommand onStartCommand()}) para aquele que solicitação de interrompimento +corresponde. Em seguida, se o serviço receber uma nova solicitação de inicialização antes de ser possível chamar {@link +android.app.Service#stopSelf(int)}, o ID não corresponderá e o serviço não será interrompido.</p> + +<p class="caution"><strong>Atenção:</strong> é importante que um aplicativo interrompa seus serviços +quando terminar os trabalhos para evitar o desperdício dos recursos do sistema e consumo da bateria. Se necessário, +outros componentes podem interromper o serviço chamando {@link +android.content.Context#stopService stopService()}. Mesmo se for possível vincular-se ao serviço, +deve-se sempre interrompê-lo por conta própria se ele tiver recebido uma chamada de {@link +android.app.Service#onStartCommand onStartCommand()}.</p> + +<p>Para obter mais informações sobre o ciclo de vida de um serviço, consulte a seção <a href="#Lifecycle">Gerenciamento do ciclo de vida de um serviço</a> abaixo.</p> + + + +<h2 id="CreatingBoundService">Criação de um serviço vinculado</h2> + +<p>Um serviço vinculado permite que componentes de aplicativo sejam vinculados chamando {@link +android.content.Context#bindService bindService()} para criar uma conexão de longo prazo +(e, geralmente, não permite que os componentes o <em>iniciem</em> chamando {@link +android.content.Context#startService startService()}).</p> + +<p>Deve-se criar um serviço vinculado quando se deseja interagir com o serviço a partir de atividades +e outros componentes no aplicativo ou para expor algumas das funcionalidades do aplicativo +para outros aplicativos, por meio de comunicação entre processos (IPC).</p> + +<p>Para criar um serviço vinculado, você deve implementar o método de retorno de chamada {@link +android.app.Service#onBind onBind()} para retornar um {@link android.os.IBinder} +que define a interface para a comunicação com o serviço. Outros componentes de aplicativo podem chamar +{@link android.content.Context#bindService bindService()} para recuperar a interface +e começar a chamar métodos no serviço. O serviço vive somente para servir o componente do aplicativo +ao qual ele está vinculado. Portanto, quando não houver componentes vinculados ao serviço, o sistema o eliminará +(<em>não</em> é necessário interromper um serviço vinculado da mesma maneira que quando o serviço é iniciado +por meio de {@link android.app.Service#onStartCommand onStartCommand()}).</p> + +<p>Para criar um serviço vinculado, a primeira coisa a se fazer é definir a interface que especifica +como um cliente pode comunicar-se com o servidor. Esta interface entre o serviço +e um cliente deve ser uma implementação de {@link android.os.IBinder} e é o que o serviço deve retornar +a partir do método de retorno de chamada {@link android.app.Service#onBind +onBind()}. Quando o cliente receber {@link android.os.IBinder}, ele poderá começar +a interagir com o serviço por meio da interface.</p> + +<p>Vários clientes podem vincular-se ao serviço por vez. Quando um cliente terminar de interagir com o serviço, + ele chamará {@link android.content.Context#unbindService unbindService()} para desvincular-se. Quando não houver +clientes vinculados ao serviço, o sistema o eliminará.</p> + +<p>Há várias maneiras de implementar um serviço vinculado e a implementação é mais complicada +que um serviço iniciado. Logo, a discussão sobre serviços vinculados aparece em um documento separado +sobre <a href="{@docRoot}guide/components/bound-services.html">Serviços vinculados</a>.</p> + + + +<h2 id="Notifications">Enviar notificações ao usuário</h2> + +<p>Quando em execução, um serviço pode notificar o usuário sobre eventos usando <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Notificações de aviso</a> ou <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notificações da barra de status</a>.</p> + +<p>Uma notificação de aviso é uma mensagem que aparece na superfície da janela atual +por um breve momento antes de desaparecer, enquanto que uma notificação da barra de status fornece um ícone na barra de status +com uma mensagem que o usuário pode selecionar para realizar uma ação (como iniciar uma atividade).</p> + +<p>Geralmente, uma notificação da barra de status é a melhor técnica quando um trabalho de segundo plano é concluído +(como download +de arquivo completo) e o usuário pode agir a partir dele. Quando o usuário seleciona a notificação a partir +da vista expandida, ela pode iniciar uma atividade (como a vista do arquivo baixado).</p> + +<p>Consulte os guias de desenvolvedor <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Notificações de aviso</a> ou <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notificações da barra de status</a> +para obter mais informações.</p> + + + +<h2 id="Foreground">Execução de serviço em primeiro plano</h2> + +<p>Um serviço de primeiro plano é aquele +com que o usuário está ativamente interagindo e não é uma opção para o sistema eliminá-lo quando a memória estiver baixa. Um serviço de primeiro plano +deve fornecer uma notificação para a barra de status, que é colocada sob +"o cabeçalho "Em andamento", o que significa que a notificação não pode ser dispensada a não ser que o serviço +seja interrompido ou removido do primeiro plano.</p> + +<p>Por exemplo, um reprodutor de música que reproduz a partir de um serviço deve ser configurado +para permanecer em execução em primeiro plano, pois o usuário está +prestando atenção em sua operação explicitamente. A notificação na barra de status pode indicar a música atual +e permitir que o usuário inicie uma atividade para interagir com o reprodutor de música.</p> + +<p>Para solicitar que o serviço seja executado em primeiro plano, chame {@link +android.app.Service#startForeground startForeground()}. Este método usa dois parâmetros: um número inteiro +que identifica unicamente a notificação e {@link +android.app.Notification} para a barra de status. Por exemplo:</p> + +<pre> +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_ID, notification); +</pre> + +<p class="caution"><strong>Atenção:</strong> O ID do número inteiro fornecido para {@link +android.app.Service#startForeground startForeground()} não deve ser zero.</p> + + +<p>Para remover o serviço do primeiro plano, chame {@link +android.app.Service#stopForeground stopForeground()}. Este método usa um booleano, +indicando se deve remover também a notificação da barra de status. Este método <em>não</em> interrompe +o serviço. No entanto, se você interromper o serviço enquanto estiver em execução em primeiro plano, +a notificação também será removida.</p> + +<p>Para obter mais informações sobre notificações, consulte <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Criação de notificações +da barra de status</a>.</p> + + + +<h2 id="Lifecycle">Gerenciamento do ciclo de vida de um serviço</h2> + +<p>O ciclo de vida de um serviço é muito mais simples do que o de uma atividade. No entanto, é ainda mais importante +que você preste muita atenção em como o serviço é criado e eliminado, pois ele +pode ser executado em primeiro plano sem que o usuário esteja ciente.</p> + +<p>O ciclo de vida do serviço — desde quando é criado até ser eliminado — pode seguir +dois caminhos:</p> + +<ul> +<li>Um serviço iniciado + <p>O serviço é criado quando outro componente chama {@link +android.content.Context#startService startService()}. Depois, o serviço permanece em execução indefinidamente e deve +interromper-se chamando {@link +android.app.Service#stopSelf() stopSelf()}. Outro componente também pode interromper +o serviço chamando {@link +android.content.Context#stopService stopService()}. Quando o serviço é interrompido, o sistema o elimina.</p></li> + +<li>Um serviço vinculado + <p>O serviço é criado quando outro componente (um cliente) chama {@link +android.content.Context#bindService bindService()}. O cliente comunica-se com o serviço +pela interface {@link android.os.IBinder}. O cliente pode escolher encerrar a conexão chamando +{@link android.content.Context#unbindService unbindService()}. Vários clientes podem ser vinculados +ao mesmo serviço e, quando todos os vínculos terminam, o sistema destrói o serviço (o serviço +<em>não</em> precisa ser interrompido).</p></li> +</ul> + +<p>Esses dois caminhos não são inteiramente separados. Ou seja, é possível vincular um serviço +que já foi iniciado com {@link android.content.Context#startService startService()}. Por exemplo, um serviço de música +de segundo plano pode ser iniciado chamando {@link android.content.Context#startService +startService()} com uma {@link android.content.Intent} que identifica a música reproduzida. Depois, +possivelmente quando o usuário quiser exercer mais controle sobre o reprodutor ou obter informações +sobre a música em reprodução, uma atividade pode ser vinculada ao serviço chamando {@link +android.content.Context#bindService bindService()}. Em casos como esse, {@link +android.content.Context#stopService stopService()} ou {@link android.app.Service#stopSelf +stopSelf()} não interrompe o serviço até que todos os clientes sejam desvinculados. </p> + + +<h3 id="LifecycleCallbacks">Implementação de retornos de chamada do ciclo de vida</h3> + +<p>Como uma atividade, um serviço tem um método de ciclo de vida que é possível implementar +para monitorar as alterações no estado do serviço e realizar trabalhos em momentos adequados. O seguinte serviço de esqueleto +demonstra cada um dos métodos de ciclo de vida:</p> + +<pre> +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 {@link android.app.Service#onCreate onCreate}() { + // The service is being created + } + @Override + public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) { + // The service is starting, due to a call to {@link android.content.Context#startService startService()} + return <em>mStartMode</em>; + } + @Override + public IBinder {@link android.app.Service#onBind onBind}(Intent intent) { + // A client is binding to the service with {@link android.content.Context#bindService bindService()} + return <em>mBinder</em>; + } + @Override + public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) { + // All clients have unbound with {@link android.content.Context#unbindService unbindService()} + return <em>mAllowRebind</em>; + } + @Override + public void {@link android.app.Service#onRebind onRebind}(Intent intent) { + // A client is binding to the service with {@link android.content.Context#bindService bindService()}, + // after onUnbind() has already been called + } + @Override + public void {@link android.app.Service#onDestroy onDestroy}() { + // The service is no longer used and is being destroyed + } +} +</pre> + +<p class="note"><strong>Observação:</strong> diferentemente dos métodos de retorno de chamada do ciclo de vida da atividade, +você <em>não</em> precisa chamar a implementação da superclasse.</p> + +<img src="{@docRoot}images/service_lifecycle.png" alt="" /> +<p class="img-caption"><strong>Figura 2.</strong> Ciclo de vida do serviço. O diagrama à esquerda +mostra o ciclo de vida quando o serviço é criado com {@link android.content.Context#startService +startService()} e o diagrama à direita mostra o ciclo de vida quando o serviço +é criado com {@link android.content.Context#bindService bindService()}.</p> + +<p>Ao implementar esses métodos, é possível monitorar dois retornos (loops) aninhados no ciclo de vida do serviço: </p> + +<ul> +<li><strong>Todo o ciclo de vida</strong> de um serviço acontece entre o momento em que {@link +android.app.Service#onCreate onCreate()} é chamado e em que {@link +android.app.Service#onDestroy} retorna. Como uma atividade, um serviço faz a sua configuração inicial +em {@link android.app.Service#onCreate onCreate()} e libera todos os recursos restantes em {@link +android.app.Service#onDestroy onDestroy()}. Por exemplo, +um serviço de reprodução de música pode criar um encadeamento onde a música será reproduzida em {@link +android.app.Service#onCreate onCreate()}, e interromperá o encadeamento em {@link +android.app.Service#onDestroy onDestroy()}. + +<p>Os métodos {@link android.app.Service#onCreate onCreate()} e {@link android.app.Service#onDestroy +onDestroy()} são chamados para todos os serviços, +se tiverem sido criados por {@link android.content.Context#startService startService()} ou {@link +android.content.Context#bindService bindService()}.</p></li> + +<li>O <strong>ciclo de vida ativo</strong> de um serviço começa com uma chamada de {@link +android.app.Service#onStartCommand onStartCommand()} ou {@link android.app.Service#onBind onBind()}. +Cada método entrega a {@link +android.content.Intent} que foi passada para {@link android.content.Context#startService +startService()} ou {@link android.content.Context#bindService bindService()}, respectivamente. +<p>Se o serviço for iniciado, o ciclo de vida ativo terminará no mesmo momento +em que o ciclo de vida inteiro terminar (o serviço permanece ativo mesmo após o retorno de {@link android.app.Service#onStartCommand +onStartCommand()}). Se o serviço estiver vinculado, o ciclo de ida ativo acabará quando {@link +android.app.Service#onUnbind onUnbind()} retornar.</p> +</li> +</ul> + +<p class="note"><strong>Observação:</strong> apesar de um serviço iniciado ser interrompido com uma chamada +de {@link android.app.Service#stopSelf stopSelf()} ou {@link +android.content.Context#stopService stopService()}, não há um retorno de chamada respectivo +para o serviço (não há retorno de chamada de {@code onStop()}). Portanto, a não ser que o serviço esteja vinculado a um cliente, +o sistema o eliminará quando for interrompido — {@link +android.app.Service#onDestroy onDestroy()} será o único retorno de chamada recebido.</p> + +<p>A figura 2 ilustra os métodos de retorno de chamada tradicionais para um serviço. Apesar de a figura separar +os serviços que são criados por {@link android.content.Context#startService startService()} +daqueles que são criados por {@link android.content.Context#bindService bindService()}, +observe que qualquer serviço, não importa como foi iniciado, pode permitir a vinculação de clientes. +Portanto, um serviço que já foi iniciado com {@link android.app.Service#onStartCommand +onStartCommand()} (por um cliente chamando {@link android.content.Context#startService startService()}) +ainda pode receber uma chamada de {@link android.app.Service#onBind onBind()} (quando um cliente chama +{@link android.content.Context#bindService bindService()}).</p> + +<p>Para obter mais informações sobre como criar um serviço que forneça vinculação, consulte o documento <a href="{@docRoot}guide/components/bound-services.html">Serviços vinculados</a>, +que aborda mais profundamente o método de retorno de chamada {@link android.app.Service#onRebind onRebind()} +na seção sobre <a href="{@docRoot}guide/components/bound-services.html#Lifecycle">Gerenciamento do ciclo de vida +de um serviço vinculado</a>.</p> + + +<!-- +<h2>Beginner's Path</h2> + +<p>To learn how to query data from the system or other applications (such as contacts or media +stored on the device), continue with the <b><a +href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b> +document.</p> +--> diff --git a/docs/html-intl/intl/pt-br/guide/components/tasks-and-back-stack.jd b/docs/html-intl/intl/pt-br/guide/components/tasks-and-back-stack.jd new file mode 100644 index 000000000000..d309c6704f37 --- /dev/null +++ b/docs/html-intl/intl/pt-br/guide/components/tasks-and-back-stack.jd @@ -0,0 +1,578 @@ +page.title=Tarefas e pilhas de retorno +parent.title=Atividades +parent.link=activities.html +@jd:body + +<div id="qv-wrapper"> +<div id="qv"> + +<h2>Neste documento</h2> +<ol> +<li><a href="#ActivityState">Gravação do estado da atividade</a></li></li> +<li><a href="#ManagingTasks">Gerenciamento de tarefas</a> + <ol> + <li><a href="#TaskLaunchModes">Definição de modos de inicialização</a></li> + <li><a href="#Affinities">Tratamento de afinidades</a></li> + <li><a href="#Clearing">Apagar a pilha de retorno</a></li> + <li><a href="#Starting">Início de uma tarefa</a></li> + </ol> +</li> +</ol> + +<h2>Artigos</h2> +<ol> + <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html"> + Multitarefa do modo Android</a></li> +</ol> + +<h2>Veja também</h2> +<ol> + <li><a href="{@docRoot}design/patterns/navigation.html">Projeto para Android: +Navegação</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">Elemento de manifesto +{@code <activity>}</a></li> + <li><a href="{@docRoot}guide/components/recents.html">Tela de visão geral</a></li> +</ol> +</div> +</div> + + +<p>Os aplicativos normalmente contêm diversas <a href="{@docRoot}guide/components/activities.html">atividades</a>. Cada atividade +deve ser projetada com relação a tipos específicos de ações que o usuário pode realizar e que podem iniciar outras +atividades. Por exemplo: um aplicativo de e-mail pode ter uma atividade para exibir uma lista de novas mensagens. +Quando o usuário seleciona uma mensagem, uma nova atividade abre para exibir essa mensagem.</p> + +<p>As atividades podem também iniciar atividades existentes em outros aplicativos no dispositivo. Por +exemplo: se o seu aplicativo deseja enviar um e-mail, é possível definir uma intenção para realizar +uma ação de "enviar" e incluir alguns dados, como um endereço de e-mail e uma mensagem. Uma atividade de outro +aplicativo que se declara para tratar deste tipo de intenções, então, abre-se. Nesse caso, a intenção +destina-se ao envio de e-mails, portanto inicia-se uma atividade de “composição" do aplicativo de e-mail (se diversas atividades +forem compatíveis com a mesma intenção, o sistema permitirá que o usuário selecione qual usar). Quando o e-mail é +enviado, sua atividade reinicia, parecendo que a atividade de e-mail faz parte do seu aplicativo. Apesar +de as atividades serem de aplicativos diferentes, o Android mantém essa experiência +do usuário retilínea mantendo ambas as atividades na mesma <em>tarefa</em>.</p> + +<p>Tarefas são coleções de atividades com as quais os usuários interagem +ao realizar determinado trabalho. As atividades são organizadas em uma pilha (a <em>pilha de retorno</em>) +na ordem em que cada atividade é aberta.</p> + +<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED +<div class="sidebox-wrapper"> +<div class="sidebox"> +<h3>Adding fragments to a task's back stack</h3> + +<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example, +suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the +other being a layout to display an item from the list (fragment B). When the user selects an item +from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be +desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p> +<p>In order to add fragment B to the back stack so that this is possible, you must call {@link +android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link +android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment +C.</p> +<p>For more information about using fragments and adding them to the back stack, see the {@link +android.app.Fragment} class documentation.</p> + +</div> +</div> +--> + +<p>A tela inicial do dispositivo é o ponto de partida para a maioria das tarefas. Quando o usuário toca em um ícone no inicializador do +aplicativo + (ou em um atalho na tela inicial), essa tarefa do aplicativo acontece em primeiro plano. Se não +existir nenhuma tarefa para o aplicativo (se o aplicativo não tiver sido usado recentemente), uma nova tarefa +será criada e a atividade "principal" daquele aplicativo abrirá como a atividade raiz na pilha.</p> + +<p>Quando a atividade atual inicia outra, a nova atividade é colocada no topo da pilha +e recebe foco. A atividade anterior permanece na pilha, mas é interrompida. Quando uma atividade +para, o sistema retém o estado atual da interface do usuário. Quando o usuário pressiona o botão +<em>Voltar</em> +, a atividade atual é retirada do topo da pilha (a atividade é destruída) +e a atividade anterior reinicia (o estado anterior da IU é restaurado). Atividades na pilha nunca +são reorganizadas, somente colocadas e retiradas da pilha — colocadas na pilha quando iniciadas +pela atividade atual e retiradas quando o usuário se retira dela usando o botão <em>Voltar</em>. Desse modo, a pilha +de retorno +opera como uma estrutura de objeto UEPS (último que entra, primeiro que sai). A figura 1 +ilustra esse comportamento com uma linha cronológica exibindo o progresso entre atividades junto com a pilha de retorno +atual em cada ponto no tempo.</p> + +<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" /> +<p class="img-caption"><strong>Figura 1.</strong> Representação de como cada nova atividade +em uma tarefa adiciona um item à pilha de retorno. Quando o usuário pressiona o botão <em>Voltar</em>, +a atividade atual é +destruída e a atividade anterior reinicia.</p> + + +<p>Se o usuário continua pressionando <em>Voltar</em>, cada atividade na pilha é retirada para +revelar +a anterior até que o usuário retorne à tela inicial (ou a qualquer atividade que estivesse em execução +no começo da tarefa). Quando todas as atividades forem removidas da pilha, a tarefa não existirá mais.</p> + +<div class="figure" style="width:287px"> +<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p +class="img-caption"><strong>Figura 2.</strong> Duas tarefas: a tarefa B recebe a interação do usuário +em primeiro plano enquanto a tarefa A está em segundo plano aguardando para ser retomada.</p> +</div> +<div class="figure" style="width:215px"> + <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p +class="img-caption"><strong>Figura 3.</strong> Uma única atividade é instanciada diversas vezes.</p> +</div> + +<p>As tarefas são unidades coesas que podem mover-se para "segundo plano" quando usuário inicia uma nova tarefa +ou ir para a tela inicial por meio do botão <em>Página inicial</em>. Quando em segundo plano, todas as atividades +da tarefa são +interrompidas, mas a pilha de retorno das tarefas continua intacta — a tarefa simplesmente perdeu o foco, +que foi para outra tarefa, como ilustrado na figura 2. Uma tarefa pode, então, retornar ao "primeiro plano" para que os usuários +continuem de onde pararam. Suponha, por exemplo, que a tarefa atual (tarefa A) tenha três +atividades na sua pilha — duas sob a atividade atual. O usuário pressiona o botão <em>Página inicial</em> e, +em seguida, +inicia um novo aplicativo no inicializador do aplicativo. Quando a tela inicial aparece, a tarefa A +vai para segundo plano. Quando o novo aplicativo inicia, o sistema inicia uma tarefa para este aplicativo +(tarefa B) com sua própria pilha de atividades. Após interagir +com este aplicativo, o usuário retorna à Página inicial novamente e seleciona o aplicativo que originalmente +iniciou a tarefa A. Agora, a tarefa A fica +em primeiro plano — todas as três atividades nas pilhas estão intactas e a atividade no topo +da pilha reinicia. Nesse +momento, o usuário pode alternar para a tarefa B acessando a Página inicial e selecionando o ícone do aplicativo +que iniciou essa tarefa (ou selecionando a tarefa do aplicativo +na <a href="{@docRoot}guide/components/recents.html">tela de visão geral</a>). +Esse é um exemplo de multitarefas no Android.</p> + +<p class="note"><strong>Observação:</strong> várias tarefas podem ser mantidas em segundo plano simultaneamente. +Contudo, se o usuário estiver executando diversas tarefas em segundo plano ao mesmo tempo, o sistema pode começar +a destruir atividades de segundo plano para recuperar memória, fazendo com que o estado das atividades seja perdido. +Consulte a seção a seguir sobre <a href="#ActivityState">Estado de atividades</a>.</p> + +<p>Como as atividades na pilha de retorno nunca são reorganizadas, se o seu aplicativo permitir que +usuários iniciem uma determinada atividade a partir de mais de uma atividade, uma nova instância +dela será criada e colocada na pilha (em vez de trazer qualquer instância anterior +dela para o topo). Assim, uma atividade no aplicativo pode ser instanciada diversas +vezes (mesmo a partir de diferentes tarefas), como ilustrado na figura 3. Assim, se o usuário navegar inversamente +usando o botão <em>Voltar</em>, as instâncias da atividade serão revelada na ordem em que foram +abertas (cada uma +com o próprio estado da IU). No entanto, é possível modificar esse comportamento se você não deseja que uma atividade seja +instanciada mais de uma vez. Esse assunto é abordado na próxima seção sobre <a href="#ManagingTasks">Gerenciamento de tarefas</a>.</p> + + +<p>Para resumir o comportamento padrão de atividades e tarefas:</p> + +<ul> + <li>Quando a atividade A inicia a atividade B, a atividade A é interrompida, mas o sistema retém seu estado +(como posição de rolagem e texto inserido em formulários). +Se o usuário pressionar o botão <em>Voltar</em> na atividade B, a atividade A reiniciará com seu estado +restaurado.</li> + <li>Quando o usuário se retira de uma tarefa pressionando o botão <em>Página inicial</em>, a atividade atual é +interrompida +e sua tarefa fica em segundo plano. O sistema retém o estado de cada atividade na tarefa. Se, +mais tarde, o usuário reiniciar a tarefa selecionando o ícone de inicialização que a inicia, ela ficará +em primeiro plano e reiniciará a atividade no topo da pilha.</li> + <li>Se o usuário pressionar o botão <em>Voltar</em>, a atividade atual será retirada da pilha +e +destruída. A atividade anterior na pilha é retomada. Quando uma atividade é destruída, o sistema +<em>não</em> retém seu estado.</li> + <li>As atividades podem ser instanciadas diversas vezes mesmo a partir de outras tarefas.</li> +</ul> + + +<div class="note design"> +<p><strong>Projeto de navegação</strong></p> + <p>Para saber mais sobre o funcionamento da navegação de aplicativos no Android, leia o guia <a href="{@docRoot}design/patterns/navigation.html">Navegação</a> do Projeto do Android.</p> +</div> + + +<h2 id="ActivityState">Gravação do estado da atividade</h2> + +<p>Como discutido acima, o comportamento padrão do sistema preserva o estado de uma atividade quando ela é +interrompida. Desse modo, quando usuários navegam inversamente a uma atividade anterior, a interface do usuário aparece +na forma em que foi deixada. Entretanto, é possível — e <strong>recomendável</strong> — reter proativamente +o estado das atividades usando métodos de retorno de chamada nos casos em que a atividade é destruída e deve +ser recriada.</p> + +<p>Quando o sistema interrompe uma das atividades (como quando uma nova atividade inicia ou a tarefa +se move para segundo plano), o sistema pode destruir esta atividade completamente se precisar recuperar +a memória do sistema. Quando isso ocorre, as informações sobre o estado da atividade são perdidas. Se isso acontecer, +o sistema ainda +saberá que a atividade tem um lugar na pilha de retorno, mas quando a atividade for levada +ao topo da pilha, o sistema precisará recriá-la (em vez de reiniciá-la). Para +evitar perder o trabalho do usuário, deve-se retê-la proativamente implementando +métodos de retorno de chamada {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} +na atividade.</p> + +<p>Para obter mais informações sobre a gravação do estado da atividade, consulte o documento +<a href="{@docRoot}guide/components/activities.html#SavingActivityState">Atividades</a>.</p> + + + +<h2 id="ManagingTasks">Gerenciamento de tarefas</h2> + +<p>O modo com que o Android gerencia tarefas e a pilha de retorno, como descrito abaixo — posicionando todas +as atividades iniciadas em sucessão na mesma tarefa em uma pilha UEPS (último que entra, primeiro que sai) — funciona +muito bem para a maioria dos aplicativo e não é preciso preocupar-se com a associação das atividades +a tarefas ou como elas estão organizadas na pilha de retorno. No entanto, pode-se decidir interromper +o comportamento normal. Talvez você deseje que uma atividade inicie uma nova tarefa no aplicativo ao ser +iniciada (em vez de ser colocada dentro da tarefa atual); ou, quando você inicia uma atividade, deseja +apresentar uma instância dela existente (em vez de criar uma nova +instância no topo da pilha de retorno); ou talvez você deseje que a pilha apague +todas as atividades, exceto a atividade raiz, quando o usuário sai da tarefa.</p> + +<p>É possível fazer tudo isso e muito mais com atributos +no elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> do manifesto + e com sinalizadores na intenção passada +a {@link android.app.Activity#startActivity startActivity()}.</p> + +<p>Com relação a isso, os principais atributos <a href="{@docRoot}guide/topics/manifest/activity-element.html"> +{@code <activity>}</a> que podem ser usados são:</p> + +<ul class="nolist"> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff"> + {@code taskAffinity}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode"> + {@code launchMode}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> + {@code allowTaskReparenting}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear"> + {@code clearTaskOnLaunch}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> + {@code alwaysRetainTaskState}</a></li> + <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish"> + {@code finishOnTaskLaunch}</a></li> +</ul> + +<p>E os principais sinalizadores de intenção que podem ser usados são:</p> + +<ul class="nolist"> + <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li> + <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li> + <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li> +</ul> + +<p>Nas seções a seguir, você verá como usar esses atributos de manifesto e sinalizadores +de intenção para definir como as atividades são associadas a tarefas e como elas se comportam na pilha de retorno.</p> + +<p>Além disso, são discutidas separadamente as considerações sobre como tarefas e atividades podem ser representadas +e gerenciadas na tela de visão geral. Consulte <a href="{@docRoot}guide/components/recents.html">Tela de visão geral</a> +para obter mais informações. Normalmente, é preciso permitir que o sistema defina como as tarefas +e as atividades são representadas na tela de visão geral e não é necessário modificar esse comportamento.</p> + +<p class="caution"><strong>Atenção:</strong> a maioria dos aplicativos não deve interromper o comportamento +padrão de atividades e tarefas. Se você determinar que é necessário modificar os comportamentos padrão +da atividade, seja prudente e certifique-se de testar a capacidade de uso da atividade durante +a inicialização e ao navegar de volta para ela de outras atividades e tarefas com o botão <em>Voltar</em>. +Certifique-se de testar os comportamentos de navegação que podem entrar em conflito com o comportamento esperado pelo usuário.</p> + + +<h3 id="TaskLaunchModes">Definição de modos de inicialização</h3> + +<p>Os modos de inicialização permitem definir a forma com que uma nova instância de uma atividade é associada +à tarefa atual. Pode-se definir diferentes modos de inicialização de duas maneiras:</p> +<ul class="nolist"> + <li><a href="#ManifestForTasks">Usando o arquivo de manifesto</a> + <p>Ao declarar uma atividade em um arquivo de manifesto, pode-se especificar como a atividade +deve associar-se a tarefas quando ela inicia.</li> + <li><a href="#IntentFlagsForTasks">Usando sinalizadores de intenção</a> + <p>Ao chamar {@link android.app.Activity#startActivity startActivity()}, +é possível incluir um sinalizador na {@link android.content.Intent} que declara como +(ou se) a nova atividade deve associar-se à tarefa atual.</p></li> +</ul> + +<p>Assim, se a atividade A iniciar a atividade B, a atividade B poderá definir no manifesto como +deve associar-se à tarefa atual (se ocorrer) e a atividade A poderá solicitar o modo pelo qual a atividade +B deverá associar-se à tarefa atual. Se ambas as atividades definem como a atividade B +deve associar-se a uma tarefa, a solicitação da atividade A (como definido na intenção) sobrepõe +a solicitação da atividade B (como definido no seu manifesto).</p> + +<p class="note"><strong>Observação:</strong> Alguns modos de inicialização disponíveis para o arquivo de manifesto +não estão disponíveis como sinalizadores para uma intenção e, do mesmo modo, alguns modos de inicialização disponíveis como sinalizadores +de uma intenção não podem ser definidos no manifesto.</p> + + +<h4 id="ManifestForTasks">Uso do arquivo de manifesto</h4> + +<p>Ao declarar uma atividade no arquivo de manifesto, pode-se especificar como a atividade +deve associar-se a tarefas usando o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code +launchMode}</a> do elemento +<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>.</p> + +<p>O atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code +launchMode}</a> especifica uma instrução sobre como a atividade deve ser inicializada +em uma tarefa. Há quatro modos diferentes de inicialização que podem ser designados ao atributo +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code>: +</p> + +<dl> +<dt>{@code "standard"} (o modo padrão)</dt> + <dd>Padrão. O sistema cria uma nova instância da atividade na tarefa +pela qual foi iniciada e encaminha-lhe a intenção. A atividade pode ser instanciada diversas vezes; +cada instância pode pertencer a diferentes tarefas e uma tarefa pode ter diversas instâncias.</dd> +<dt>{@code "singleTop"}</dt> + <dd>Se uma instância da atividade já existir no topo da tarefa atual, o sistema +encaminhará a intenção àquela instância por meio de uma chamada do método {@link +android.app.Activity#onNewIntent onNewIntent()} em vez de criar uma nova instância +da atividade. A atividade pode ser instanciada diversas vezes; cada instância pode +pertencer a diferentes tarefas e uma tarefa pode ter diversas instâncias (mas somente se +a atividade no topo da pilha de retorno <em>não</em> for uma instância existente da atividade). + <p>Por exemplo: suponhamos que uma pilha de retorno da tarefa consista na atividade raiz A com as atividades B, C e +D no topo (a pilha é A-B-C-D, com D no topo). Uma intenção chega de uma atividade de tipo D. +Se D for o modo de inicialização {@code "standard"} padrão, uma nova instância da classe será inicializada +e a tarefa se tornará A-B-C-D-D. Entretanto, se o modo de inicialização de D for {@code "singleTop"}, a instância existente +de D receberá a intenção por {@link +android.app.Activity#onNewIntent onNewIntent()} porque ela está no topo da pilha — +a pilha permanece A-B-C-D. Contudo, se uma intenção chegar de uma atividade de tipo B, uma nova +instância de B será adicionada à pilha, mesmo que o modo de inicialização seja {@code "singleTop"}.</p> + <p class="note"><strong>Observação:</strong> quando uma nova instância de uma atividade é criada, +o usuário pode pressionar o botão <em>Voltar</em> para retornar à atividade anterior. Porém, quando uma +instância +existente de uma atividade trata de uma nova intenção, o usuário não pode pressionar o botão <em>Voltar</em> para retornar +ao estado +da atividade antes que a nova intenção chegue em {@link android.app.Activity#onNewIntent +onNewIntent()}.</p> +</dd> + +<dt>{@code "singleTask"}</dt> + <dd>O sistema cria uma nova tarefa e instancia a atividade em sua raiz. +Entretanto, se uma instância da atividade já existir em uma tarefa separada, o sistema encaminhará +a intenção àquela instância por meio de uma chamada do método {@link +android.app.Activity#onNewIntent onNewIntent()} em vez de criar uma nova instância. Somente +uma instância da atividade pode existir por vez. + <p class="note"><strong>Observação:</strong> embora a atividade inicie em uma nova tarefa, o botão +<em>Voltar</em> ainda direciona o usuário à atividade anterior.</p></dd> +<dt>{@code "singleInstance"}.</dt> + <dd>Igual à {@code "singleTask"}, exceto que o sistema não inicializa nenhuma outra atividade +na tarefa que contém a instância. A atividade é sempre o único e exclusivo membro de sua tarefa; +toda atividade iniciada por ela abre em uma tarefa separada.</dd> +</dl> + + +<p>Outro exemplo: o aplicativo Navegador do Android declara que a atividade do navegador da web deve +sempre abrir na própria tarefa — especificando o modo de inicialização {@code singleTask} no elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>. +Isso significa que, se o aplicativo emite uma +intenção para abrir o navegador do Android, sua atividade <em>não</em> é colocada na mesma +tarefa do aplicativo. Em vez disso, uma nova tarefa inicia para o navegador ou, se o navegador +já possui uma tarefa em execução em segundo plano, essa tarefa é colocada em primeiro plano para tratar a nova +intenção.</p> + +<p>Se uma atividade inicia em uma nova tarefa ou na mesma tarefa que a atividade que +a iniciou, o botão <em>Voltar</em> sempre direciona o usuário à atividade anterior. Porém, se você +iniciar uma atividade que especifica o modo de inicialização {@code singleTask} e se uma instância +dessa atividade existir em uma tarefa de segundo plano, toda a tarefa será colocada em primeiro plano. Nesse +momento, a pilha de retorno conterá todas as atividades da tarefa colocada em primeiro plano +no topo. A figura 4 ilustra essa situação.</p> + +<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" /> +<p class="img-caption"><strong>Figura 4.</strong> Representação de como uma atividade +com modo de inicialização "singleTask" é adicionada à pilha de retorno. Se a atividade já for parte de uma tarefa +de segundo plano com a própria pilha de retorno, toda a pilha também virá +para primeiro plano, no topo da tarefa atual.</p> + +<p>Para obter mais informações sobre o uso de modos de inicialização no arquivo de manifesto, consulte a documentação do elemento +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +, onde o atributo {@code launchMode} e os valores aceitos +são discutidos mais aprofundadamente.</p> + +<p class="note"><strong>Observação:</strong> os comportamentos a especificar para a atividade com o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> + podem ser neutralizados por sinalizadores incluídos na intenção que inicia a atividade, conforme abordado +na próxima seção.</p> + + + +<h4 id="#IntentFlagsForTasks">Uso de sinalizadores de intenção</h4> + +<p>Ao iniciar uma atividade, é possível modificar a associação padrão de uma atividade à tarefa +incluindo sinalizadores na intenção fornecida a {@link +android.app.Activity#startActivity startActivity()}. Os sinalizadores que podem ser usados para modificar +o comportamento padrão são:</p> + +<p> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt> + <dd>Inicia a atividade em uma nova tarefa. Se uma tarefa já estiver em execução para a atividade que você está +iniciando agora, ela será colocada em primeiro plano com o último estado restaurado e a atividade +receberá a nova intenção em {@link android.app.Activity#onNewIntent onNewIntent()}. + <p>Isso produz o mesmo comportamento que o valor {@code "singleTask"} do <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>, +abordado na seção anterior.</p></dd> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt> + <dd>Se a atividade iniciada for a atual (no topo da pilha de retorno), +a instância existente receberá uma chamada de {@link android.app.Activity#onNewIntent onNewIntent()} +em vez de criar uma nova instância da atividade. + <p>Isso produz o mesmo comportamento que o valor {@code "singleTop"} do <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> +abordado na seção anterior.</p></dd> + <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt> + <dd>Se a atividade iniciada já estiver em execução na tarefa atual, em vez +de lançar uma nova instância daquela atividade, todas as outras atividades no topo dela serão +destruídas e essa intenção será entregue à instância reiniciada da atividade (agora no topo) +por {@link android.app.Activity#onNewIntent onNewIntent()}. + <p>Não há nenhum valor para o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> + que produza esse comportamento.</p> + <p>{@code FLAG_ACTIVITY_CLEAR_TOP} é mais usado em conjunto com + {@code FLAG_ACTIVITY_NEW_TASK}. +Quando usados juntos, estes sinalizadores são o modo de localizar uma atividade existente +em outra tarefa e colocá-la em uma posição em que possa responder à intenção. </p> + <p class="note"><strong>Observação:</strong> se o modo de inicialização da atividade designada for +{@code "standard"}, +ela também será removida da pilha e uma nova instância será iniciada em seu lugar para tratar +a intenção recebida. Isso se deve ao fato de que uma nova instância é sempre criada para uma nova intenção quando o +modo de inicialização é {@code "standard"}. </p> +</dd> +</dl> + + + + + +<h3 id="Affinities">Tratamento de afinidades</h3> + +<p>A <em>afinidade</em> indica a que tarefa uma atividade prefere pertencer. Por padrão, todas +as atividades do mesmo aplicativo têm afinidade entre si. Assim, por padrão, todas +as atividades no mesmo aplicativo preferem estar na mesma tarefa. Contudo, é possível modificar +a afinidade padrão de uma atividade. Atividades definidas +em aplicativos diferentes podem compartilhar uma afinidade, ou atividades definidas no mesmo aplicativo podem ter +diferentes afinidades de tarefa atribuídas.</p> + +<p>É possível modificar a afinidade de qualquer atividade com o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> + do elemento +<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>.</p> + +<p>O atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> + recebe um valor de string que deve ser exclusivo do nome do pacote padrão +declarado no elemento <a href="{@docRoot}guide/topics/manifest/manifest-element.html"> +{@code <manifest>} +</a> porque o sistema usa esse nome para identificar a afinidade +de tarefa padrão do aplicativo.</p> + +<p>A afinidade tem relevância em duas circunstâncias:</p> +<ul> + <li>Quando a intenção que inicializa uma atividade contém + o sinalizador + {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}. + +<p>Uma nova atividade é, por padrão, inicializada na tarefa da atividade +que chamou {@link android.app.Activity#startActivity startActivity()}. Ela é colocada na mesma +pilha de retorno do autor da chamada. Contudo, se a intenção passada a +{@link android.app.Activity#startActivity startActivity()} +contiver o sinalizador {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} +, o sistema procurará uma tarefa diferente para comportar a nova atividade. Na maioria das vezes, é uma nova tarefa. +Porém, isso não é obrigatório. Se já houver uma tarefa com a mesma afinidade +da nova atividade, ela será inicializada naquela tarefa. Caso contrário, ela iniciará uma nova tarefa.</p> + +<p>Se esse sinalizador fizer com que uma atividade inicie uma nova tarefa e se o usuário pressionar o botão <em>Página inicial</em> +para sair dela, + será necessário ter um modo de o usuário navegar de volta à tarefa. Algumas entidades (como +o gerenciador de notificação) sempre iniciam atividades em tarefas externas, nunca como parte de si mesmas, por isso +elas sempre colocam {@code FLAG_ACTIVITY_NEW_TASK} nas intenções que passam +a {@link android.app.Activity#startActivity startActivity()}. +Se você tiver uma atividade que possa ser chamada +por uma entidade externa que possa usar este sinalizador, certifique-se de que o usuário tenha um modo independente +de voltar à tarefa iniciada, como com um ícone de inicialização (a atividade raiz da tarefa +tem um filtro de intenções {@link android.content.Intent#CATEGORY_LAUNCHER}; consulte a seção <a href="#Starting">Início de uma tarefa</a> abaixo).</p> +</li> + + <li>Quando uma atividade tem o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent"> +{@code allowTaskReparenting}</a> definido como {@code "true"}. + <p>Nesse caso, a atividade pode mover-se da tarefa que iniciou para a tarefa afim +quando for colocada em primeiro plano.</p> + <p>Por exemplo: suponhamos que uma atividade que relate condições do clima em cidades selecionadas seja +definida como parte de um aplicativo de viagens. Ela tem a mesma afinidade que outras atividades no mesmo +aplicativo (a afinidade padrão do aplicativo) e permite a redefinição da hierarquia com esse atributo. +Quando uma das atividades inicia a atividade de notificação de clima, ela inicialmente pertence à mesma +tarefa de sua atividade. Porém, quando a tarefa do aplicativo de viagens é colocada em primeiro plano, +a atividade de notificação de clima é reatribuída a essa tarefa e exibida dentro dela.</p> +</li> +</ul> + +<p class="note"><strong>Dica:</strong> se um arquivo {@code .apk} contiver mais de um "aplicativo" +do ponto de vista do usuário, você provavelmente desejará usar o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> + para designar diferentes afinidades às atividades associadas a cada "aplicativo".</p> + + + +<h3 id="Clearing">Apagar a pilha de retorno</h3> + +<p>Se o usuário sair de uma tarefa por muito tempo, o sistema apagará a tarefa de todas as atividades exceto +a da atividade raiz. Quando o usuário retornar à tarefa, somente a atividade raiz será restaurada. +O sistema comporta-se dessa maneira porque, após longo tempo de uso, os usuários provavelmente abandonaram +o que estavam fazendo antes e são direcionados de volta à tarefa para começar algo novo. </p> + +<p>Há alguns atributos de atividade que podem ser usados para modificar esse comportamento: </p> + +<dl> +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> +</dt> +<dd>Se esse atributo for definido como {@code "true"} na atividade raiz de uma tarefa, +o comportamento padrão descrito não acontecerá. +A tarefa reterá todas as atividades em sua pilha mesmo após um longo período.</dd> + +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt> +<dd>Se esse atributo for definido como {@code "true"} na atividade raiz de uma tarefa, +a pilha será apagada da atividade raiz sempre que o usuário sair da tarefa +e retornar a ela. Em outras palavras, é o oposto de +<a href="{@docRoot}guide/topics/manifest/activity-element.html#always"> +{@code alwaysRetainTaskState}</a>. O usuário sempre retorna à tarefa +no estado inicial, mesmo ao retirar-se da tarefa somente por um momento.</dd> + +<dt><code><a +href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> +</dt> +<dd>Esse atributo é como <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>, +mas opera +em uma única atividade, e não em uma tarefa inteira. Ele também apaga todas as atividades, +inclusive a atividade raiz. Quando definido como {@code "true"}, +a atividade permanece parte da tarefa somente para a sessão atual. Se o usuário +retirar-se e, em seguida, retornar à tarefa, ela não estará mais presente.</dd> +</dl> + + + + +<h3 id="Starting">Início de uma tarefa</h3> + +<p>É possível configurar uma atividade como ponto de entrada de uma tarefa fornecendo-lhe um filtro de intenções +com {@code "android.intent.action.MAIN"} como a ação especificada +e {@code "android.intent.category.LAUNCHER"} +como a categoria especificada. Por exemplo:</p> + +<pre> +<activity ... > + <intent-filter ... > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + ... +</activity> +</pre> + +<p>Um filtro de intenções desse tipo faz com que um ícone e o rótulo +da atividade sejam exibidos no inicializador do aplicativo, fornecendo aos usuários um modo de inicializar a atividade +e de retornar à tarefa criada a qualquer tempo após sua inicialização. +</p> + +<p>Este segundo recurso é importante: é preciso que os usuários possam sair de uma tarefa e voltar a ela +mais tarde usando esse inicializador de atividades. Por isso, os dois <a href="#LaunchModes">modos +de inicialização</a> que marcam atividades como sempre iniciando uma tarefa ({@code "singleTask"} e +{@code "singleInstance"}) devem ser usados somente quando a atividade tiver um filtro +{@link android.content.Intent#ACTION_MAIN} +e um {@link android.content.Intent#CATEGORY_LAUNCHER}. Imagine, por exemplo, o que +aconteceria se o filtro não estivesse presente: uma intenção inicializaria uma atividade {@code "singleTask"}, iniciando uma +nova tarefa, e o usuário perderia algum tempo trabalhando nessa tarefa. O usuário, então, pressiona o botão +<em>Página inicial</em>. A tarefa é enviada para segundo plano e não fica mais visível. O usuário não tem como voltar +à tarefa porque ela não é representada no inicializador do aplicativo.</p> + +<p>Para esses casos em que se deseja que o usuário não seja capaz de retornar a uma atividade, defina +<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a> + do elemento +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> +como {@code "true"} (consulte <a href="#Clearing">Apagar a pilha</a>).</p> + +<p>Veja mais informações sobre a representação e o gerenciamento de atividades +na tela de visão geral em <a href="{@docRoot}guide/components/recents.html"> +Tela de visão geral</a>.</p> + +<!-- +<h2>Beginner's Path</h2> + +<p>For more information about how to use intents to +activate other application components and publish the intents to which your components +respond, continue with the <b><a +href="{@docRoot}guide/components/intents-filters.html">Intents and Intent +Filters</a></b> document.</p> +--> |