应用安装位置
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
从 API 级别 8 开始,您可以允许将应用安装到外部存储装置(例如,设备的 SD 卡)。您可以使用 android:installLocation
清单属性为您的应用声明此可选功能。如果不声明此属性,应用就只会安装到内部存储设备,并且无法移至外部存储装置。
如需允许系统将您的应用安装到外部存储装置,请修改您的清单文件,以便在 <manifest>
元素中添加 android:installLocation
属性,该属性的值为“preferExternal
”或“auto
”。例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >
如果声明“preferExternal
”,表示您请求将应用安装到外部存储装置,不过系统不保证会将应用安装到外部存储装置。如果外部存储空间已满,系统会将应用安装到内部存储设备。用户还可以在两个位置之间移动应用。
如果声明“auto
”,表示您同意可以将应用安装到外部存储装置,但您对安装位置并无偏好。系统会根据多个因素决定应用的安装位置。用户还可以在两个位置之间移动应用。
当应用安装在外部存储装置中时:
- 只要外部存储装置是安装到设备上的,便不会对应用性能产生影响。
.apk
文件保存在外部存储装置中,但所有用户私有数据、数据库、经过优化的 .dex
文件和已提取的原生代码都保存在内部设备内存中。
- 存储应用的唯一容器使用随机生成的密钥进行加密,该密钥只能由最初安装该应用的设备解密。因此,安装在 SD 卡上的应用仅适用于一台设备。
- 用户可以通过系统设置将应用移至内部存储设备。
警告:当用户通过启用 USB 大容量存储与计算机共享文件时,或通过系统设置卸载 SD 卡时,外部存储装置将从设备中卸载,在外部存储装置上运行的所有应用也将立即终止。
向后兼容性
将应用安装到外部存储装置的功能仅在搭载 API 级别 8 (Android 2.2) 或更高级别操作系统的设备上可用。在 API 级别 8 之前构建的现有应用将始终安装在内部存储设备中,并且无法移至外部存储装置(即使在搭载 API 级别 8 的设备上也是如此)。不过,如果应用的设计目的是支持低于 8 的 API 级别,您可以选择在搭载 API 级别 8 或更高级别操作系统的设备上支持此功能,同时仍与 API 级别低于 8 的设备兼容。
如需允许在外部存储装置中安装应用并仍与低于 API 级别 8 的版本兼容,请执行以下操作:
- 在
<manifest>
元素中添加 android:installLocation
属性,该属性的值为“auto
”或“preferExternal
”。
- 保持
android:minSdkVersion
属性不变(例如低于“8”),并确保应用代码仅使用与该级别兼容的 API。
- 为编译应用,请将构建目标更改为 API 级别 8。此为必要操作,因为版本更低的 Android 库不了解
android:installLocation
属性,也不会在存在应用时对其进行编译。
如果在 API 级别低于 8 的设备上安装应用,android:installLocation
属性会被忽略,应用会安装到内部存储设备中。
注意:虽然版本更低的平台会忽略此类 XML 标记,但您必须小心,除非是在代码中提供向后兼容性所必需,否则不要在 minSdkVersion
低于“8”时使用 API 级别 8 中引入的编程 API。
不应安装到外部存储装置的应用
当用户通过启用 USB 大容量存储与计算机共享文件(或以其他方式卸载或移除外部存储装置)时,安装在外部存储装置上且当前正在运行的任何应用都会终止。在停用大容量存储并在设备上重新安装外部存储装置之前,这些应用对系统而言相当于不存在。除了终止应用并使用户无法使用应用外,此举可能还会对某些类型的应用造成更加严重的破坏。为使应用始终按预期运行,如果应用使用以下任何功能,您不应允许将其安装到外部存储装置,因为卸载外部存储装置时会出现下述后果:
- 服务
- 正在运行的
Service
会终止,并且在重新安装外部存储装置后也不会重启。绑定到该服务的应用可以注册 ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
广播 intent,当安装在外部存储装置中的应用再次对系统可用时,该广播 intent 将通知所有未安装在外部存储装置上的应用。收到此广播后,应用可以尝试绑定到您的服务。
- 闹钟 Service
- 利用
AlarmManager
注册的闹钟会被取消。重新安装外部存储装置后,您必须手动重新注册所有闹钟。
- 输入法引擎
- 您的 IME 会替换为默认 IME。重新安装外部存储装置后,用户可以打开系统设置再次启用 IME。
- 动态壁纸
- 正在运行的动态壁纸会替换为默认动态壁纸。重新安装外部存储装置后,用户可以再次选择您的动态壁纸。
- 应用微件
- 您的应用微件会从主屏幕中移除。重新安装外部存储装置后,在系统重置主应用之前(通常直到系统重新启动后才会重置),用户无法选择您的应用微件。
- 账号管理器
- 在重新安装外部存储装置之前,使用
AccountManager
创建的账号会消失。 - 同步适配器
- 在重新安装外部存储装置之前,您的
AbstractThreadedSyncAdapter
及其所有同步功能将不起作用。 - 设备管理器
- 您的
DeviceAdminReceiver
及其所有管理功能都会停用,这可能会对设备功能产生无法预料的后果,这些后果甚至可能会在重新安装外部存储装置后继续存在。 - 监听“启动已完成”的广播接收器
- 在将外部存储装置安装到设备之前,系统会发出
ACTION_BOOT_COMPLETED
广播。如果应用安装在外部存储装置上,将永远无法接收此广播。
如果您的应用使用上述任一功能,您不应允许将应用安装到外部存储装置。默认情况下,系统不会允许应用安装到外部存储装置,因此您无需担心现有应用。但是,如果您确定应用绝对不应安装到外部存储装置,那么您应该通过声明值为“internalOnly
”的 android:installLocation
以明确这一点。虽然这不会更改默认行为,但会明确指出您的应用只应安装在内部存储设备中,并提醒您和其他开发者已作出此决定。
应安装到外部存储装置的应用
简言之,只要不使用前文所列的功能,应用安装到外部存储装置时便安全无虞。大型游戏通常属于应允许安装到外部存储装置的应用类型,因为游戏通常不在非活动状态时提供其他服务。如果外部存储装置变得不可用且游戏进程被终止,当该存储装置再次可用且用户重启游戏时(假设游戏在正常的 Activity 生命周期中正确保存了其状态),应该不会有明显的影响。
如果应用需要数兆字节空间供 APK 文件使用,您应认真考虑是否允许应用安装在外部存储装置上,以便用户可以保留其内部存储设备上的空间。
如需了解其他相关信息,请参阅:<manifest>
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-07-27。
[null,null,["最后更新时间 (UTC):2025-07-27。"],[],[],null,["# App install location\n\nBeginning with API Level 8, you can allow your application to be installed on the\nexternal storage (for example, the device's SD card). This is an optional feature you can declare\nfor your application with the [`android:installLocation`](/guide/topics/manifest/manifest-element#install) manifest attribute. If you do\n*not* declare this attribute, your application will be installed on the internal storage\nonly and it cannot be moved to the external storage.\n\nTo allow the system to install your application on the external storage, modify your\nmanifest file to include the [`android:installLocation`](/guide/topics/manifest/manifest-element#install) attribute in the [\u003cmanifest\u003e](/guide/topics/manifest/manifest-element) element,\nwith a value of either \"`preferExternal`\" or \"`auto`\". For example: \n\n```xml\n\u003cmanifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n android:installLocation=\"preferExternal\"\n ... \u003e\n```\n\nIf you declare \"`preferExternal`\", you request that your application be installed on the\nexternal storage, but the system does not guarantee that your application will be installed on\nthe external storage. If the external storage is full, the system will install it on the internal\nstorage. The user can also move your application between the two locations.\n\nIf you declare \"`auto`\", you indicate that your application may be installed on the\nexternal storage, but you don't have a preference of install location. The system will\ndecide where to install your application based on several factors. The user can also move your\napplication between the two locations.\n\nWhen your application is installed on the external storage:\n\n- There is no effect on the application performance so long as the external storage is mounted on the device.\n- The `.apk` file is saved on the external storage, but all private user data, databases, optimized `.dex` files, and extracted native code are saved on the internal device memory.\n- The unique container in which your application is stored is encrypted with a randomly generated key that can be decrypted only by the device that originally installed it. Thus, an application installed on an SD card works for only one device.\n- The user can move your application to the internal storage through the system settings.\n\n**Warning:** When the user enables USB mass storage to share files\nwith a computer or unmounts the SD card via the system settings, the external storage is unmounted\nfrom the device and all applications running on the external storage are immediately killed.\n\nBackward compatibility\n----------------------\n\nThe ability for your application to install on the external storage is a feature available only\non devices running API Level 8 (Android 2.2) or greater. Existing applications that were built prior\nto API Level 8 will always install on the internal storage and cannot be moved to the external\nstorage (even on devices with API Level 8). However, if your application is designed to support an\nAPI Level *lower than* 8, you can choose to support this feature for devices with API Level 8\nor greater and still be compatible with devices using an API Level lower than 8.\n\nTo allow installation on external storage and remain compatible with versions lower than API\nLevel 8:\n\n1. Include the `android:installLocation` attribute with a value of \"`auto`\" or \"`preferExternal`\" in the [\u003cmanifest\u003e](/guide/topics/manifest/uses-sdk-element) element.\n2. Leave your `android:minSdkVersion` attribute as is (something *less\n than* \"8\") and be certain that your application code uses only APIs compatible with that level.\n3. In order to compile your application, change your build target to API Level 8. This is necessary because older Android libraries don't understand the `android:installLocation` attribute and will not compile your application when it's present.\n\nWhen your application is installed on a device with an API Level lower than 8, the `android:installLocation` attribute is ignored and the application is installed on the internal\nstorage.\n\n**Caution:** Although XML markup such as this will be ignored by\nolder platforms, you must be careful not to use programming APIs introduced in API Level 8\nwhile your `minSdkVersion` is less than \"8\", unless you perform the work necessary to\nprovide backward compatibility in your code.\n\nApplications that should NOT install on external storage\n--------------------------------------------------------\n\nWhen the user enables USB mass storage to share files with their computer (or otherwise\nunmounts or removes the external storage), any application\ninstalled on the external storage and currently running is killed. The system effectively becomes\nunaware of the application until mass storage is disabled and the external storage is\nremounted on the device. Besides killing the application and making it unavailable to the user,\nthis can break some types of applications in a more serious way. In order for your application to\nconsistently behave as expected, you **should not** allow your application to be\ninstalled on the external storage if it uses any of the following features, due to the cited\nconsequences when the external storage is unmounted:\n\nServices\n: Your running\n [Service](/reference/android/app/Service) is\n killed and isn't restarted when external storage is remounted. Applications\n bound to this service can register for the\n [ACTION_EXTERNAL_APPLICATIONS_AVAILABLE](/reference/android/content/Intent#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)\n broadcast intent, which notifies all applications that *aren't*\n installed on external storage when the applications installed on external\n storage have become available to the system again. After receiving this\n broadcast, applications can attempt to bind to your service.\n\nAlarm Services\n: Your alarms registered with [AlarmManager](/reference/android/app/AlarmManager) will be cancelled. You must\n manually re-register any alarms when external storage is remounted.\n\nInput Method Engines\n: Your [IME](/guide/topics/text/creating-input-method) will be\n replaced by the default IME. When external storage is remounted, the user can open system settings\n to enable your IME again.\n\nLive Wallpapers\n: Your running [Live Wallpaper](http://android-developers.blogspot.com/2010/02/live-wallpapers.html)\n will be replaced by the default Live Wallpaper. When external storage is remounted, the user can\n select your Live Wallpaper again.\n\nApp Widgets\n: Your [App Widget](/guide/topics/appwidgets) will be removed\n from the home screen. When external storage is remounted, your App Widget will *not* be\n available for the user to select until the system resets the home application (usually not until a\n system reboot).\n\nAccount Managers\n: Your accounts created with [AccountManager](/reference/android/accounts/AccountManager) will disappear until\n external storage is remounted.\n\nSync Adapters\n: Your [AbstractThreadedSyncAdapter](/reference/android/content/AbstractThreadedSyncAdapter) and all its sync functionality will\n not work until external storage is remounted.\n\nDevice Administrators\n: Your [DeviceAdminReceiver](/reference/android/app/admin/DeviceAdminReceiver) and all its admin capabilities will\n be disabled, which can have unforeseeable consequences for the device functionality, which may\n persist after external storage is remounted.\n\nBroadcast Receivers listening for \"boot completed\"\n: The system delivers the [ACTION_BOOT_COMPLETED](/reference/android/content/Intent#ACTION_BOOT_COMPLETED) broadcast\n before the external storage is mounted to the device. If your application is installed on the\n external storage, it can never receive this broadcast.\n\nIf your application uses any of the features listed above, you **should not** allow\nyour application to install on external storage. By default, the system *will not* allow your\napplication to install on the external storage, so you don't need to worry about your existing\napplications. However, if you're certain that your application should never be installed on the\nexternal storage, then you should make this clear by declaring [`android:installLocation`](/guide/topics/manifest/manifest-element#install) with a value of \"`internalOnly`\". Though this does not\nchange the default behavior, it explicitly states that your application should only be installed\non the internal storage and serves as a reminder to you and other developers that this decision has\nbeen made.\n\nApplications that should install on external storage\n----------------------------------------------------\n\nIn simple terms, anything that does not use the features listed in the previous section\nare safe when installed on external storage. Large games are more commonly the types of\napplications that should allow installation on external storage, because games don't typically\nprovide additional services when inactive. When external storage becomes unavailable and a game\nprocess is killed, there should be no visible effect when the storage becomes available again and\nthe user restarts the game (assuming that the game properly saved its state during the normal\n[Activity lifecycle](/guide/components/activities#Lifecycle)).\n\nIf your application requires several megabytes for the APK file, you should\ncarefully consider whether to enable the application to install on the external storage so that\nusers can preserve space on their internal storage.\n\nFor additional related information, refer to:[\\\u003cmanifest\\\u003e](/guide/topics/manifest/manifest-element)"]]