Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

Tela de visão geral

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 atividades e tarefas 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.

Figura 1. A tela de visão geral mostrando três documentos do Google Drive, cada um representado como uma tarefa separada.

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, seu aplicativo pode determinar como e quando as atividades aparecem na tela de visão geral. A classe ActivityManager.AppTask permite gerenciar tarefas e os sinalizadores de atividade da classe Intent permitem especificar quando uma atividade é adicionada ou removida da tela de visão geral. Além disso, os atributos <activity> permitem definir o comportamento no manifesto.

Adição de tarefas à tela de visão geral

Usar os sinalizadores da classe 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 <activity>, é possível escolher entre sempre abrir o documento em uma nova tarefa ou reutilizar uma tarefa existente para o documento.

Uso do sinalizador Intent para adicionar uma tarefa

Ao criar um novo documento para a atividade, você chama o método startActivity() da classe ActivityManager.AppTask, passando-lhe o intent 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 FLAG_ACTIVITY_NEW_DOCUMENT no método addFlags() da Intent que inicia a atividade.

Observação: O sinalizador FLAG_ACTIVITY_NEW_DOCUMENT substitui o sinalizador FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET, obsoleto a partir do Android 5.0 (API de nível 21).

Se você usar o sinalizador 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:

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 = 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++;
  }
}

Observação: Atividades iniciadas com o sinalizador FLAG_ACTIVITY_NEW_DOCUMENT devem ter o valor do atributo android:launchMode="standard" (o padrão) definido no manifesto.

Quando a atividade principal inicia uma nova atividade, o sistema procura nas tarefas existentes uma cujo intent corresponda ao nome do componente do intent e aos dados de Intent da atividade. Se a tarefa não for encontrada ou se o intent continha o sinalizador 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á o novo intent para onNewIntent(). A nova atividade receberá o intent e criará um novo documento na tela de visão geral, como no exemplo a seguir:

NewDocumentActivity.java

@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);
}

Uso do atributo Activity para adicionar uma tarefa

Uma atividade também pode especificar em seu manifesto que sempre iniciará 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 aplicativo:

"intoExisting"
A atividade reutiliza uma tarefa existente para o documento. Isso é o mesmo que configurar o sinalizador FLAG_ACTIVITY_NEW_DOCUMENT sem configurar o sinalizador FLAG_ACTIVITY_MULTIPLE_TASK, como descrito em Uso do sinalizador Intent para adicionar uma tarefa acima.
always
A atividade cria uma nova tarefa para o documento, mesmo se ele já estiver aberto. Usar esse valor é o mesmo que configurar os sinalizadores FLAG_ACTIVITY_NEW_DOCUMENT e FLAG_ACTIVITY_MULTIPLE_TASK.
"none”"
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.
"never"
A atividade não cria uma nova tarefa para o documento. Definir esse valor modifica o comportamento dos sinalizadores FLAG_ACTIVITY_NEW_DOCUMENT e FLAG_ACTIVITY_MULTIPLE_TASK, caso um deles esteja definido no intent, e a tela de visão geral exibe uma tarefa para o aplicativo, que retoma a atividade invocada por último pelo usuário.

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

Remoção de tarefas

Por padrão, uma tarefa de documento é automaticamente removida da tela de visão geral quando a atividade termina. Esse comportamento pode ser modificado com a classe ActivityManager.AppTask, com um sinalizador Intent ou com um atributo <activity>.

É possível excluir inteiramente uma tarefa da tela de visão geral definindo o atributo <activity> , android:excludeFromRecents como true.

É possível definir o número máximo de tarefas que o aplicativo pode incluir na tela de visão geral definindo o atributo <activity> android:maxRecents 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 android:maxRecents é 50 (25 em dispositivos com pouca memória); valores menores que 1 não são válidos.

Uso da classe AppTask para remover tarefas

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 finishAndRemoveTask().

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

Retenção de tarefas terminadas

Se você deseja reter uma tarefa na tela de visão geral, mesmo que a atividade tenha terminado, passe o sinalizador FLAG_ACTIVITY_RETAIN_IN_RECENTS no método addFlags() do intent que inicia a atividade.

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

Para obter o mesmo efeito, defina o atributo <activity> android:autoRemoveFromRecents como false. O valor padrão é true para atividades de documentos e false para atividades comuns. Usar esse atributo modifica o sinalizador FLAG_ACTIVITY_RETAIN_IN_RECENTS discutido anteriormente.