Google 致力于为黑人社区推动种族平等。查看具体举措

Activity 启动政策

Activity 启动行为由应用 AndroidManifest.xml 文件中的启动模式、Intent 标记以及调用程序提供的 ActivityOptions 定义。使用 ActivityOption#setLaunchDisplayId(int) 可针对 Activity 启动将特定屏幕指定为目标。

  • 默认情况下,Activity 与调用程序在同一个屏幕上启动。例如,通过启动器启动的新 Activity 实例应该放置在同一个屏幕上,而不含其他标记或选项。务必使用正确的上下文(Activity 与应用)进行启动。
  • 如果通过与特定屏幕无关的来源执行启动(例如通过 shell 或应用上下文),则 Activity 会放置在用户最后一次与设备互动或启动最后一个 Activity 所在的顶部屏幕上。
  • 用于启动 Activity 的 Intent 可解析为系统中已有的 Activity 实例。在这种情况下,如果未提供其他标记,则 Activity 会显示在最后一次使用它所在的屏幕上。如果使用 ActivityOptions#setTargetDisplayId() 指定目标屏幕,则 Activity 会移动到该屏幕(如果安全限制及其他限制允许的话)。

安全限制

在 Android 10 中,为了防止恶意应用通过从其创建的虚拟屏幕的表面读取用户敏感信息来盗用相关信息,应用只能在其创建的虚拟屏幕上启动其自己的 Activity。不过:

  • 具有 INTERNAL_SYSTEM_WINDOW 权限的系统组件可以在任何屏幕上启动
  • 具有 ACTIVITY_EMBEDDING 权限的调用程序可以从具有 ActivityInfo.FLAG_ALLOW_EMBEDDED 标记的其他应用启动 Activity
  • 仅允许所有者或相应屏幕上存在 Activity 时在个人屏幕上启动 Activity

向屏幕添加窗口会受到类似限制。

Android 10 包含 ActivityManager#isActivityStartAllowedOnDisplay(Context context, int displayId, Intent intent) 方法,用于先检查应用的安全限制,然后再尝试在屏幕上启动。在 Android 9(及更低版本)中,受限制的启动结果会抛出 SecurityException

大多数安全限制都通过 ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay() 方法应用。