“Recents”屏幕(screen)(也称为“OverView”屏幕,最近的任务列表或最近的应用程序)是一个系统级UI,列出最近访问的活动(Activity)和任务(task)。用户可以浏览列表并选择要恢复的任务,或者用户可以通过将其移除来从列表中删除任务。 Android 5.0(API级别21)引入了 document-centric模型,其中包含在不同文档(document)的同一Activity的多个实例可能在“最近”屏幕中显示为任务。例如,Google云端硬盘可能会为多个Google文档中的每个文档执行任务。每个文档在“最近”屏幕中均显示为任务。
图一:“Recents”屏幕显示三个Google云端硬盘文档,每个文档都表示为单独的任务。另一个常见示例是当用户使用他们的浏览器时,他们点击分享---> Gmail。将显示Gmail应用程序的“编辑”屏幕。此时点按“最近”按钮会显示Chrome和Gmail分别作为单独的任务运行。在较低版本的Android中,所有Activity都显示为单个任务,使“后退”按钮成为唯一的导航方式。图2显示了与平台的较低版本相比,最高安卓屏幕在Android 5.0及更高版本中的外观。 Android 5.0及更高版本的左侧屏幕上的图像,右侧的图像显示了它在Android的较低版本中的显示方式。
图二:"最近"屏幕在Android5.0及以上(左)和Android5.0以上(右)的区别通常,您应该允许系统在“最近”屏幕中定义您的任务和活动的表示方式,而不需要修改此行为。但是,您的应用可以确定活动在“最近”屏幕中的显示方式和时间。 ActivityManager.AppTask类允许您管理任务,Intent类的Activity标志允许您指定何时在“最近”屏幕中添加或删除活动。此外,允许您在manifest中通过设置<activity>的属性来达到此目的。
使用Intent类的flag添加任务可以更好地控制document在“最近”屏幕中何时以及如何打开或重新打开。使用<activity>属性时,您可以选择始终在新任务中打开document或重用document的现有任务。
为Activity创建新document时,可以调用startActivity()方法,并向其传递启动Activity的Intent。要插入逻辑中断(logical break)以便系统将您的Activity视为“最近”屏幕中的新任务,请在启动Activity的Intent的addFlags()方法中传递FLAG_ACTIVITY_NEW_DOCUMENT标志。
注意:FLAG_ACTIVITY_NEW_DOCUMENT标志替换了FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET标志,该标志自Android 5.0(API级别21)起不推荐使用。
如果在创建新document时设置FLAG_ACTIVITY_MULTIPLE_TASK标志,则系统始终以目标活动为根创建新任务。此设置允许在多个任务中打开同一文档。以下代码演示了Main 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; } }
注意:使用FLAG_ACTIVITY_NEW_DOCUMENT标志启动的Activity必须在manifest中设置android:launchMode =“standard”属性值(默认值)。
当main activity启动新activity时,系统会在现有任务中搜索一个与Intent component name和Intent data 匹配的task。如果未找到task,或者intent包含FLAG_ACTIVITY_MULTIPLE_TASK标志,则将创建一个以Activity为根的新任务。如果找到一个,它会将该任务带到前面并将新Intent传递给onNewIntent()。新Activity获取Intent并在“最近”屏幕中创建新document,如以下示例所示:
-
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>的android:documentLaunchMode属性启动到新任务。此属性有四个值,当用户使用应用程序打开document时,这些值会产生以下效果:
- “intoExisting” Activity重用该文档的现有task。这与设置FLAG_ACTIVITY_NEW_DOCUMENT标志而不设置FLAG_ACTIVITY_MULTIPLE_TASK标志相同,如上面使用Intent标志添加任务中所述。
- “always” 即使document已经打开,activity也会为document创建新任务。使用此值与设置FLAG_ACTIVITY_NEW_DOCUMENT和FLAG_ACTIVITY_MULTIPLE_TASK标志相同。
- “none” Activity不会为document创建新任务。 “最近”窗口按默认情况处理activity:它显示应用程序的单个任务,该任务从用户上次调用的任何activity中恢复。
- “never” Activity不会为document创建新任务。设置此值将覆盖FLAG_ACTIVITY_NEW_DOCUMENT和FLAG_ACTIVITY_MULTIPLE_TASK标志的行为,如果在intent中设置了其中任何一个,并且“最近”屏幕显示应用程序的单个任务,该任务将从用户上次调用的任何activity中恢复。
注意:对于非none以外的值,永远不必使用launchMode =“standard”定义activity。如果未指定此属性,则使用documentLaunchMode =“none”。
默认情况下,documen task在其activity完成时会自动从“最近”屏幕中删除。您可以使用ActivityManager.AppTask类,使用Intent标志或使用<activity>属性覆盖此行为。
您始终可以通过将<activity>的android:excludeFromRecents属性设置为true从“最近”屏幕中排除任务。
您可以通过将<activity>的android:maxRecents属性设置为整数值来设置应用程序可以包含在“最近”窗口中的最大任务数。默认值为16.达到最大任务数时,将从“最近”屏幕中删除最近最少使用的任务。 android:maxRecents最大值为50(低内存设备上为25);小于1的值无效。
在“最近”窗口中创建新任务的Activity中,您可以通过调用finishAndRemoveTask()方法指定何时删除任务并finish与其关联的所有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(); }
注意:使用finishAndRemoveTask()方法会覆盖FLAG_ACTIVITY_RETAIN_IN_RECENTS标记的使用,如下所述。
如果你想在最近任务中保留一个即使他的activity已经finishedtask,应该在启动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。document activity的默认值为true,常规activity的默认值为false。使用此属性会覆盖之前讨论的FLAG_ACTIVITY_RETAIN_IN_RECENTS标志。
要下载有关以document centric的示例应用,请参见 Android DocumentCentricRecents Sample 和 Android DocumentCentricRelinquishIdentity Sample.