通常情况下,应用不应依赖于静态标识符或基于某些屏幕 ID 的逻辑。在大多数情况下,应用应该能够适应在不同尺寸的屏幕上工作,而系统应控制应用的放置位置。例如,针对可折叠设备打造新颖独特的体验,并且当设备处于折叠状态时,在外部屏幕上启动特定的应用。
在这种情况下,SystemUI(或其他系统组件)应检测设备是否处于折叠状态,确定是否应该执行操作,然后启动目标 activity 并指定一个外部屏幕 ID 作为启动目标。应用不应检测此操作,也不应做出响应,然后在特定屏幕上启动。换句话说,不要假设可在一台设备上执行的操作,也可在其他设备上执行。简而言之,专门针对特定设备的代码会导致碎片化程度增加。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Recommended practices\n\nApps for foldable and multi-screen devices\n------------------------------------------\n\nGenerally, apps should not rely on static identifiers or logic that depends on\nsome display IDs. In most cases, apps should resize and work on different displays\nand the system should control where to locate apps. For example, to build a\nnew and unique experience for foldable devices and launch a special app on the\nexternal screen when the device is folded.\n\nIn this case, SystemUI (or another system component) should detect the\nfold, determine if it's appropriate to perform an action, and then launch the\ntarget activity and specify an external display ID as the launch target.\n\nApps shouldn't detect this action or perform any action in response and then\nperform the launch on a specific display. In other words, do not assume that\nwhat works on one device will work on other devices. In short, device-specific\ncode increases fragmentation.\n\nRestrict access to displays\n---------------------------\n\nIf the device configuration requires the restriction of access to one or more\ndisplays, the recommendation is to use the `Display#FLAG_PRIVATE` flag\nto designate such displays as *private* . Doing so restricts all but the\nowner from adding content to the display. Any attempt to launch an activity or to\nadd a window by anyone but the owner results in a `SecurityException`.\nIf the system owns the display, the system can add windows and launch activities.\n\nIn addition, entities placed on a display can always access that display.\nIf the owner launches an activity on a display, then the activity can launch other\nactivities on this display. As a result, the owner is responsible for restricting\naccess and allowing trusted apps *only*.\n\nIn addition, more restrictions are added to virtual displays because any app can\ncreate one without making it visible to the user. If the virtual display isn't\nowned by the system, then only activities with\n[allowEmbedded](https://developer.android.com/guide/topics/manifest/activity-element#embedded)\nare permitted and the caller should have the `ACTIVITY_EMBEDDING`\npermission.\n\nFor more information, see:\n\n- `ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()`\n- `ActivityDisplay#isUidPresent()`\n- `DisplayManagerService#isUidPresentOnDisplay()`\n\nTo conditionally control activity launches, use `LaunchParamsController`,\nwhich intercepts all activity launches and allows a system component to modify the\nparameters used for launch. This is available in `system_server`.\n\nConfigure display windowing settings and system decorations\n-----------------------------------------------------------\n\n[System decorations](/docs/core/display/multi_display/system-decorations#decorations) can\nbe configured per display in `DisplayWindowSettings`. A device\nimplementation can provide a default configuration in\n`/data/system/display_settings.xml`.\n\nThis value determines whether system decorations (launcher, wallpaper,\nnavigation bar, and other decor windows) and the IME appear on a display.\nFor details, see `DisplayWindowSettings#shouldShowSystemDecorsLocked()`\nand `DisplayWindowSettings#shouldShowImeLocked()`.\n\nTo identify the display, use either a unique ID (this default uses\n`DisplayInfo#uniqueId`) or a physical port ID for hardware\ndisplays (see `DisplayInfo#address`).\n\nFor example, the following display config example enables system decorations and the\nIME on a simulated display: \n\n```text\n\u003c?xml version='1.0' encoding='utf-8' standalone='yes' ?\u003e\n\u003cdisplay-settings\u003e\n\u003cconfig identifier=\"0\" /\u003e\n\u003cdisplay\n name=\"overlay:1\"\n shouldShowSystemDecors=\"true\"\n shouldShowIme=\"true\" /\u003e\n\u003c/display-settings\u003e\n```\n\nIn the example above, `uniqueId` is used for display identification\nin the name attribute, which for a simulated display is `overlay:1`.\nFor a built-in display, a sample value may be `\"local:45354385242535243453\"`.\nAnother option is to use hardware port information and set `identifier=\"1\"`\nto correspond to `DisplayWindowSettings#IDENTIFIER_PORT` and then update the\nname to use the `\"port:\u003cport_id\u003e\"` format: \n\n```text\n\u003c?xmlversion='1.0' encoding='utf-8' standalone='yes' ?\u003e\n\u003cdisplay-settings\u003e\n\u003cconfig identifier=\"1\" /\u003e\n\u003cdisplay\n name=\"port:12345\"\n shouldShowSystemDecors=\"true\"\n shouldShowIme=\"true\" /\u003e\n\u003c/display-settings\u003e\n```\n\nFor details, see [Static display identifiers](/docs/core/display/multi_display/displays#static).\n| **Key Point:** Because some settings are read once per system boot, updating a value at runtime may not take effect until the system is next rebooted. `display_settings.xml` is persisted in the `/data/` directory. A factory wipe can erase this file. Therefore, if a device implementation provides a default configuration in `display_settings.xml`, be sure to provide the configuration before WindowManager is initialized.\n\nFor more information, see:\n\n- [Display window settings](/docs/core/display/multi_display/displays#windows)\n- [Static display identifiers](/docs/core/display/multi_display/displays#static)\n- [System decorations support](/docs/core/display/multi_display/system-decorations)"]]