“最近”屏幕

“最近使用的应用”屏幕(也称为“概览”屏幕、近期任务列表或“最近用过的应用”屏幕)是一个系统级界面,其中列出了最近访问过的 activity任务。用户可以浏览该列表,选择要恢复的任务,或者通过滑动将任务从列表中移除。

“最近使用的应用”屏幕使用在 Android 5.0(API 级别 21)中引入的以文档为中心的模型。在该模型中,包含不同文档的同一 activity 的多个实例可以作为任务显示在“最近使用的应用”屏幕中。例如,Google 云端硬盘可能针对多个 Google 文档中的每个文档都有一个任务。每个文档都会在“最近使用的应用”屏幕中显示为一项任务:

“最近使用的应用”屏幕,显示了两个 Google 云端硬盘文档,每个文档表示为一个单独的任务。

另一个常见示例是,当用户使用浏览器时,他们点按共享 > Gmail。系统会显示 Gmail 应用的写邮件屏幕。此时点按“最近”按钮会显示 Chrome 和 Gmail 作为单独的任务运行:

“最近使用的应用”屏幕,显示 Chrome 和 Gmail 作为单独的任务运行。

通常,您可以让系统定义任务和 activity 在“最近使用的应用”屏幕中的表示方式。您无需修改此行为。不过,您的应用可以确定 activity 在“最近使用的应用”屏幕中的显示方式和时间。

您可以使用 ActivityManager.AppTask 类管理任务,使用 Intent 类的 activity 标志可以指定何时在“最近使用的应用”屏幕中添加或移除 activity。此外,您还可以使用 <activity> 属性在清单中设置行为。

将任务添加到“最近使用的应用”屏幕

通过使用 Intent 类的标志添加任务,您可以更好地控制文档在“最近使用的应用”屏幕中打开或重新打开的时间和方式。使用 <activity> 属性时,您可以选择始终在新任务中打开文档,或者对文档重复使用现有任务。

使用 Intent 标志添加任务

为 activity 创建新文档时,您可以调用 startActivity() 方法,并向其传递启动 activity 的 intent。如需插入逻辑广告插播时间点,以便系统在“最近使用的应用”屏幕中将您的 activity 视为新任务,请在启动 activity 的 IntentaddFlags() 方法中传递 FLAG_ACTIVITY_NEW_DOCUMENT 标志。

如果您在创建新文档时设置 FLAG_ACTIVITY_MULTIPLE_TASK 标志,系统始终会以目标 activity 作为根创建新任务。此设置可让同一文档在多个任务中打开。以下代码演示了主 activity 如何执行此操作:

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

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

}

当主 activity 启动新 activity 时,系统会在现有任务中搜索 intent 与该 activity 的 intent 组件名称和 intent 数据相匹配的任务。如果未找到该任务,或者 intent 包含 FLAG_ACTIVITY_MULTIPLE_TASK 标志,则系统会创建一个新任务,并以该 activity 作为其根。

如果系统找到 intent 与 intent 组件名称和 intent 数据匹配的任务,则会将该任务置于前台,并将新的 intent 传递给 onNewIntent()。新 activity 会获取 intent,并在“最近使用的应用”屏幕中创建新文档,如以下示例所示:

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

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

使用 activity 属性添加任务

activity 还可以使用 <activity> 属性 android:documentLaunchMode 在其清单中指定它始终启动到新任务。该属性有四个值,在用户使用应用打开文档时分别会产生以下效果:

intoExisting
Activity 重复使用文档的现有任务。这与在未设置 FLAG_ACTIVITY_MULTIPLE_TASK 标志的情况下设置 FLAG_ACTIVITY_NEW_DOCUMENT 标志相同,如使用 intent 标志添加任务部分中所述。
always
activity 会为文档创建新任务,即使文档已打开也是如此。使用此值与同时设置 FLAG_ACTIVITY_NEW_DOCUMENTFLAG_ACTIVITY_MULTIPLE_TASK 标志的效果相同。
none
Activity 不会为文档创建新任务。“最近使用的应用”屏幕会以默认方式处理 activity。它为应用显示单个任务,该任务将从用户上次调用的任何 activity 开始继续执行。
never
Activity 不会为文档创建新任务。设置此值会替换 FLAG_ACTIVITY_NEW_DOCUMENTFLAG_ACTIVITY_MULTIPLE_TASK 标志的行为。如果在 intent 中设置了其中任何一项,并且“最近使用的应用”屏幕为应用显示单个任务,则该应用将从用户上次调用的任意 activity 开始继续执行。

移除任务

默认情况下,文档任务会在其 activity 结束时自动从“最近使用的应用”屏幕退出。您可以使用 ActivityManager.AppTask 类、Intent 标志或 <activity> 属性替换此行为。

您可以随时通过将 <activity> 属性 android:excludeFromRecents 设置为 true,将任务从“最近使用的应用”屏幕中完全排除。

您可以通过将 <activity> 属性 android:maxRecents 设置为整数值,设置应用可在“最近使用的应用”屏幕中包含的任务数上限。达到任务数上限时,最近最少使用的任务会从“最近使用的应用”屏幕中消失。默认值为 16,最大值为 50(低内存设备上为 25)。小于 1 的值无效。

使用 AppTask 类移除任务

对于在“最近使用的应用”屏幕中创建新任务的 activity,您可以通过调用 finishAndRemoveTask() 方法来指定何时移除该任务并完成与该任务关联的所有 activity:

Kotlin

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

Java

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

保留已完成的任务

如果您想在“最近使用的应用”屏幕中保留某个任务(即使该任务的 activity 已完成),请在启动该 activity 的 intent 的 addFlags() 方法中传递 FLAG_ACTIVITY_RETAIN_IN_RECENTS 标志。

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

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

如需达到同样的效果,请将 <activity> 属性 android:autoRemoveFromRecents 设置为 false。文档活动的默认值为 true,常规活动的默认值为 false。使用此属性会替换 FLAG_ACTIVITY_RETAIN_IN_RECENTS 标志。

启用最近使用的网址共享功能(仅限 Pixel)

在搭载 Android 12 或更高版本的 Pixel 设备上,用户可以直接从“最近”屏幕分享最近浏览过的 Web 内容的链接。在某个应用中访问内容后,用户可以滑动到“最近使用的应用”屏幕并找到查看该内容的应用,然后点按链接按钮以复制或分享该网址。

“最近”屏幕,其中包含用于分享最近浏览过的 Web 内容的链接。

任何应用都可以通过提供网页界面和替换 onProvideAssistContent() 来为用户启用“最近”关联,如以下示例所示:

Kotlin

class MainActivity : AppCompatActivity() {
    protected fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun onProvideAssistContent(outContent: AssistContent) {
        super.onProvideAssistContent(outContent)
        outContent.setWebUri(Uri.parse("https://example.com/myCurrentPage"))
    }
}

Java

public class MainActivity extends AppCompatActivity {

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

    @Override
    public void onProvideAssistContent(AssistContent outContent) {
        super.onProvideAssistContent(outContent);

        outContent.setWebUri(Uri.parse("https://example.com/myCurrentPage"));
    }
}