Tela "Recentes"

A tela Recentes, também chamada de tela "Visão geral", lista de tarefas ou apps recentes, é uma IU do sistema que lista as atividades e tarefas acessadas recentemente. O usuário pode navegar pela lista e selecionar uma tarefa para ser retomada ou pode remover uma tarefa da lista deslizando-a para fora. O Android 5.0 (API de nível 21) introduz um modelo centrado em documentos, em que várias instâncias da mesma atividade que contêm documentos diferentes podem aparecer como tarefas na tela Recentes. Por exemplo, o Google Drive pode ter uma tarefa para cada um dos diversos documentos do Google. Cada documento aparece como uma tarefa na tela Recentes.

Figura 1. A tela Recentes mostrando três documentos do Google Drive, cada um representado como uma tarefa separada.

Outro exemplo comum é quando o usuário está usando o navegador e toca em Compartilhar > Gmail. A tela Escrever do app Gmail aparece. Ao tocar no botão Recentes nesse momento, o Chrome e o Gmail são executados como tarefas separadas. Nas versões anteriores do Android, todas as atividades aparecem como uma única tarefa, tornando o botão "Voltar" o único meio de navegação. A Figura 2 mostra como a tela Recentes aparece no Android 5.0 e versões posteriores, em comparação com versões anteriores da plataforma. A imagem na tela à esquerda é para o Android 5.0 e versões posteriores, e a imagem à direita mostra como ela aparece em versões anteriores do Android.

Visualizações pré-Android 5.0 comparadas com visualizações mais antigas da tela

Figura 2. Tela Recentes no Android 5.0 e versões posteriores (esquerda) e em versões anteriores ao Android 5.0 (direita).

Normalmente, você precisa permitir que o sistema defina como suas tarefas e atividades são representadas na tela Recentes, e não é necessário modificar esse comportamento. No entanto, seu app pode determinar como e quando as atividades aparecem na tela Recentes. A classe ActivityManager.AppTask permite que você gerencie tarefas, e as sinalizações de atividade da classe Intent permitem que você especifique quando uma atividade será adicionada ou removida da tela Recentes. Além disso, os atributos <activity> permitem definir o comportamento no manifesto.

Como adicionar tarefas à tela "Recentes"

Usar as sinalizações da classe Intent para adicionar uma tarefa permite maior controle sobre quando e como um documento é aberto ou reaberto na tela Recentes. Ao usar os atributos <activity>, você pode escolher entre sempre abrir o documento em uma nova tarefa ou reutilizar uma tarefa existente para o documento.

Como usar a sinalização de intent para adicionar uma tarefa

Ao criar um novo documento para sua atividade, você chama o método startActivity(), transmitindo para ele o intent que inicia a atividade. Para inserir uma quebra lógica para que o sistema trate sua atividade como uma nova tarefa na tela Recentes, transmita a sinalização FLAG_ACTIVITY_NEW_DOCUMENT no método addFlags() do Intent que inicia a atividade.

Observação: a sinalização FLAG_ACTIVITY_NEW_DOCUMENT substitui a sinalização FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, que ficou obsoleta a partir do Android 5.0 (API de nível 21).

Se você definir a sinalização FLAG_ACTIVITY_MULTIPLE_TASK ao criar o novo documento, o sistema sempre criará uma nova tarefa com a atividade de destino como a 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:

Kotlin

    fun createNewDocument(view: View) {
        val newDocumentIntent = newDocumentIntent()
        if (useMultipleTasks) {
            newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
        }
        startActivity(newDocumentIntent)
    }

    private fun newDocumentIntent(): Intent =
            Intent(this, NewDocumentActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
                        android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)
                putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, documentCounter++)
            }

    

Java

DocumentCentricActivity.java

    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 = checkbox.isChecked();
          final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
          newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
          newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, documentCounter++);
          return newDocumentIntent;
      }

    }
    

Observação: as atividades iniciadas com a sinalização FLAG_ACTIVITY_NEW_DOCUMENT precisam ter o valor de atributo android:launchMode="standard" (o padrão) definido no manifesto.

Quando a atividade principal inicia uma nova atividade, o sistema pesquisa as tarefas existentes por uma cujo intent corresponda ao nome do componente do intent e aos dados do intent da atividade. Se a tarefa não for encontrada ou se o intent contiver a sinalização FLAG_ACTIVITY_MULTIPLE_TASK, uma nova tarefa será criada com a atividade como raiz. Se uma tarefa for encontrada, ela é levada para a frente e o novo intent é transmitido para onNewIntent(). A nova atividade receberá o intent e criará um novo documento na tela Recentes, como no exemplo a seguir:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_new_document)
        documentCount = intent
                .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0)
        documentCounterTextView = findViewById(R.id.hello_new_document_text_view)
        setDocumentCounterText(R.string.hello_new_document_counter)
    }

    override fun onNewIntent(newIntent: Intent) {
        super.onNewIntent(newIntent)
        /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this Activity
        will be reused. */
        setDocumentCounterText(R.string.reusing_document_counter)
    }
    

Java

NewDocumentActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_document);
        documentCount = getIntent()
                .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0);
        documentCounterTextView = (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);
    }
    

Como usar o atributo da atividade para adicionar uma tarefa

Uma atividade também pode especificar no manifesto que ela sempre se inicia em uma nova tarefa usando o atributo <activity>, android:documentLaunchMode. Esse atributo tem quatro valores que produzem os seguintes efeitos quando o usuário abre um documento com o app:

"intoExisting"
A atividade reutiliza uma tarefa existente para o documento. Isso é o mesmo que definir a sinalização FLAG_ACTIVITY_NEW_DOCUMENT sem definir a sinalização FLAG_ACTIVITY_MULTIPLE_TASK, como descrito acima em Como usar a sinalização de intent para adicionar uma tarefa.
"always"
A atividade cria uma nova tarefa para o documento, mesmo se o documento já estiver aberto. Usar esse valor é o mesmo que definir as sinalizações FLAG_ACTIVITY_NEW_DOCUMENT e FLAG_ACTIVITY_MULTIPLE_TASK.
"none"
A atividade não cria uma nova tarefa para o documento. A tela Recentes trata a atividade como faria por padrão: ela exibe uma única tarefa para o app, que é retomada a partir de qualquer atividade que o usuário tenha invocado pela última vez.
"never"
A atividade não cria uma nova tarefa para o documento. A definição desse valor modifica o comportamento das sinalizações FLAG_ACTIVITY_NEW_DOCUMENT e FLAG_ACTIVITY_MULTIPLE_TASK, se uma delas for definida no intent, e a tela Recentes exibe uma única tarefa para o app, que é retomada de qualquer atividade que o usuário tenha invocado pela última vez.

Observação: para valores diferentes de none e never, a atividade precisa ser definida com launchMode="standard". Se esse atributo não for especificado, documentLaunchMode="none" será usado.

Como remover tarefas

Por padrão, uma tarefa de documento é automaticamente removida da tela Recentes quando a atividade dela termina. Você pode modificar esse comportamento com a classe ActivityManager.AppTask, com uma sinalização Intent ou com um atributo <activity>.

Você pode excluir uma tarefa da tela Recentes por completo sempre que quiser, basta configurar o atributo <activity>, android:excludeFromRecents para true.

Você pode definir o número máximo de tarefas que seu app pode incluir na tela Recentes definindo o atributo <activity> android:maxRecents como um valor inteiro. O padrão é 16. Quando o número máximo de tarefas for atingido, a tarefa usada menos recentemente será removida da tela Recentes. O valor máximo de android:maxRecents é 50, sendo 25 em dispositivos com pouca memória. Valores menores que 1 não são válidos.

Como usar a classe AppTask para remover tarefas

Na atividade que cria uma nova tarefa na tela Recentes, você pode especificar quando remover a tarefa e concluir todas as atividades associadas a ela chamando o método finishAndRemoveTask().

Kotlin

    fun onRemoveFromOverview(view: View) {
        // It is good pratice to remove a document from the overview stack if not needed anymore.
        finishAndRemoveTask()
    }
    

Java

NewDocumentActivity.java

    public void onRemoveFromRecents(View view) {
        // The document is no longer needed; remove its task.
        finishAndRemoveTask();
    }
    

Observação: o uso do método finishAndRemoveTask() modifica o uso da tag FLAG_ACTIVITY_RETAIN_IN_RECENTS, discutida abaixo.

Como reter tarefas concluídas

Se você quiser manter uma tarefa na tela Recentes, mesmo que sua atividade tenha terminado, transmita a sinalização FLAG_ACTIVITY_RETAIN_IN_RECENTS no método addFlags() do intent que inicia a atividade.

Kotlin

    private fun newDocumentIntent() =
            Intent(this, NewDocumentActivity::class.java).apply {
                addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT or
                        android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS)
                putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, getAndIncrement())
            }
    

Java

DocumentCentricActivity.java

    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, getAndIncrement());
        return newDocumentIntent;
    }
    

Para conseguir o mesmo efeito, defina o atributo <activity> android:autoRemoveFromRecents para false. O valor padrão é true para atividades de documentos, e false para atividades regulares. O uso desse atributo modifica a sinalização FLAG_ACTIVITY_RETAIN_IN_RECENTS, discutida anteriormente.

Outras amostras de código

Para fazer o download de um app de amostra sobre apps de documentos, consulte a Amostra DocumentCentricRecents e a Amostra DocumentCentricRelinquishIdentity do Android (links em inglês).