从 API 8 开始(参考官方文档:App Install Location | Android Developers),你可以将你的应用安装在外部储存中(例如,安装到设备的 SD 卡上)。这是一个可选的特征,你可以在你的应用的 AndroidManifest.xml 中声明 android:installLocation 属性。如果你没有声明这个属性,你的应用程序将会被安装在内部储存,并且不能被移到外置储存中。

修改 AndroidManifest.xml 文件中 <manifest> 元素下的 android:installLocation 属性,赋值为 “preferExternal” 或 “auto”,即可允许系统将应用安装到外部存储中。代码如下:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >

如果 android:installLocation 属性声明为 preferExternal,意味着你要求应用程序安装在外置储存,但是系统不保证你的程序一定会被安装在外部储存中。如果外部储存空间已满,程序将会被安装在内部储存。用户也可以在两个储存之间移动你的应用程序。如果声明了 auto,表明你的应用程序可以安装在外部储存,但是你没有一个安装位置的偏好。系统会根据一些因素来决定你的应用程序安装在哪。用户也可以在两个储存之间移动你的程序。

当你的应用被安装在外部储存时:

  • 只要外部存储一直挂载在设备上,就不会对应用的性能造成影响。
  • .apk 文件会储存在外部储存中,但所有私有的用户数据,数据库,优化的 .dex 文件,和提取的本地的代码都会保存在内部储存中。
  • 存储应用的特定容器被一个随机生成的 Key 加密,并且只能被最初安装这个应用的设备解密。这样就可以保证一个安装在 SD 卡上的应用只为唯一的设备服务。
  • 用户可以通过系统设置将应用移到内部储存中。

▐ 注意:当用户启用 USB 大容量存储与电脑共享文件或通过系统设置卸载 SD 卡时,外部存储就会从设备卸载同时所有运行在外部存储的应用会被立即杀死。

Backward Compatibility

只有在运行 API 8(Android 2.2)或更高版本的设备上才可以将应用安装到外部存储中,在 API 8 之前建立的应用只能被安装到内部存储中,并且不能移动到外部存储中(即使在 API 8 的设备上)。如果要求应用支持 API < 8 的设备,你可以让运行 API  >= 8 的设备使用这个特性,也可通过如下的设置来兼容 API < 8 的设备。

  1. 在 AndroidManifest.xml 文件 <manifest> 元素中设置的 android:installLocation 属性为 auto 或 perferExternal。
  2. 保持  android:minSdkVersion 属性不变(一个小于8的数)并保证你应用代码所使用的 API 与之相符。
  3. 在编译你的应用之前,将  build target 的 API 级别修改为 8。因为低版本的 Android 库不识别 android:installLocation 属性,因此也就不会在该属性存在的情况下编译应用。

当你的应用安装在一个运行 API < 8 的设备上时,android:installLocation 属性会被忽略,并且应用程序会被安装到内部存储中。

▐ 注意:尽管通过 XML 标记可以让低版本的平台忽略这个问题,但仍然要小心的是,当 minSdkVersion < 8 的时候,不要在编程过程中引入级别为 8 的 API,除非你的代码需要向后兼容。

Applications That Should NOT Install on External Storage

当用户启用 USB 大容量存储与计算机共享文件(通过其他方式卸载或移除外部存储),任何安装在外部存储并正在运行的程序都会被杀死。直到大容量存储处于不可用状态,外部存储重新被挂载到设备上,系统才会识别这些应用。除了杀死应用使得它对用户不可用之外,还会通过一些更危险的方式破坏某些类型的应用程序。如果你的应用使用了如下特征,会在外部存储卸载的时出现引用问题,所以你应该禁止你的应用安装在外部存储中。

服务(Services)

正在运行的服务会被杀死,并且在外部存储被重新挂载后也不会重启。但是你可以注册一个 ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 的广播,这样应用程序就可以在外置存储可用时接收到通知并重启服务。

警报服务(Alarm Services)

使用 AlarmManager 注册的 Alarm Services 将被取消。你必须在外置存储被重新挂载的时候重新手动的注册 Alarm Services。

输入法引擎(Input Method Engines)

你的 IME 将会被替换为默认的 IME。当外部存储重新挂载的时候,用户可以在系统设置中激活自己的 IME。

动态壁纸(Live Wallpapers)

动态壁纸会被替换为默认的动态壁纸。外部存储重新挂载的时候,用户可以重新选择自己之前的壁纸。

窗口小部件(App Widgets)

应用程序的 App Widget 会被移除,即使外部存储重新被挂载,用户也无法使用该应用的 App Widget,除非系统重置 Home 应用(通常要等到系统重启)。

账户管理器(Account Managers)

通过 AccountManager 创建的账户会消失,直到外部存储重新挂载后在可用。

同步适配器(Sync Adapters)

AbstractThreadedSyncAdapter 以及它的一切异步方法将停止工作,同样也的等到外部存储重新挂载后才能恢复正常。

设备管理员(Device Administrators)

你的 DeviceAdminReceiver 及其所有管理功能将被禁用,这可能对设备造成不可预见的后果。

监听“启动完成”的广播接收者(Broadcast Receivers listening for "boot completed")

系统会在外部存储挂载到设备之前发出 ACTION_BOOT_COMPLETED 广播。如果你的应用程序安装在外部存储器,它永远不会收到此广播。

如果你的应用程序使用了上面列出的功能,你不应该允许你的应用安装到外部存储。默认情况下,系统将不允许你的应用安装到外部存储,所以你不需要担心你现有的应用程序。然而,如果你非常确定你的应用不应该安装到外部存储,那么你应该声明 android:installLocation 的值为 “internalOnly”。但这并不会改变默认的行为,它只是很明确的提醒你和其他的开发者这个应用只应该被安装在内部存储中。

Applications That Should Install on External Storage

简单来说,只要你的应用没有使用上节中列出的特性,那么安装到外部存储中就是安全的。大型游戏通常会允许安装到外部存储中,因为游戏通常不会在闲置状态提供额外的服务。当外部存储不可用时,游戏进程会被杀死,当外置储存变得可用而且用户重启游戏时,不应该有明显的影响(假设游戏在它正常的 Activity 生命周期适当的保存了状态)。

如果你应用程序的 APK 文件占用很大字节的存储空间,你应该仔细的考虑是否将应用安装到外部存储中,以便为用户节省内部存储空间。

Android 编程下 App Install Location的更多相关文章

  1. Android 编程下的代码混淆之(android-support-v4.jar)

    项 目在代码混淆过程中如果引用了第三方 Jar 包,需要在混淆的脚本文件中加入第三方 Jar 包的声明.部分第三方 Jar 包虽然在混淆脚本中进行了声明,但是在混淆过程中经常会发现内部类或者引用文件找 ...

  2. Android 编程下 Managing Your App's Memory

    Managing Your App's Memory Random-access memory (RAM) 在任何软件开发环境中都是宝贵的资源,它在物理内存有限的移动操作系统中更为宝贵.虽然 Andr ...

  3. Android 编程下通过 Theme 和 Style 避免 APP 启动闪黑屏

    之前在做 APP 的时候不太关注这个问题,因为自己在使用其他 APP 的时候也会在应用启动的初始有一个黑屏闪过后才会出现应用的欢迎页.直到最近开发过程中发现自己在欢迎页启动的线程由于请求和处理的数据量 ...

  4. Android 编程下 Touch 事件的分发和消费机制

    Android 中与 Touch 事件相关的方法包括:dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent ev). ...

  5. Android 编程下的代码混淆

    什么是代码混淆 Java 是一种跨平台的.解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中.由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名.方法名,并且通 ...

  6. Android系统下app测试功能点

    一.安装卸载 1.验证app能否正常的安装启动运行,安装后的文件夹及文件是否写到了指定的目录里,卸载后相关文件是否清除 2.软件安装/卸载过程中意外情况的处理是否符合需求(如死机,重启,断电) 3.安 ...

  7. Android 编程下的 TraceView 简介及其案例实战

    TraceView 是 Android 平台配备一个很好的性能分析的工具.它可以通过图形化的方式让我们了解我们要跟踪的程序的性能,并且能具体到 method.详细内容参考:Profiling with ...

  8. 【转】Android 编程下的代码混淆

    什么是代码混淆 代码混淆(Obfuscated code)亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为.代码混淆可以用于程序源代码,也可以用于程序编译而成的中 ...

  9. Android 编程下字库的使用

    在安卓操作系统下对于 TextView 字体的支持很有限,默认情况下 TextView 的 typeface 属性支持 "Sans","serif"," ...

随机推荐

  1. Constructing Roads (MST)

    Constructing Roads Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  2. 【Swoole应用教程】一、Swoole扩展的编译安装部署

    介绍swoole扩展,从源码的下载,环境依赖,编译参数配置,常见编译问题,安装,配置等内容.期间还会介绍: Linux发行版本的选择 不同版本内核的差异 gcc/g++/clang 3种编译器介绍 a ...

  3. PHP5 Session 使用详解(一)

    http协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议.所谓无 状态,指的是不会维护http请求数据,http请求是独立的,不持久的.而越来越复杂的WEB应用,需要保存一些用户 ...

  4. 【UGUI】Canvas和Rect Transform

    Canvas 1.所有的UI元件都需要放在Canvas里 2.UI元件的绘制顺序,与在 Hierarchy的顺序相同,在上面的元素会先被绘制,位于后续绘制元素的下面 3.可以选择3种不同的渲染模式: ...

  5. 1.10 编程之美-双线程下载[double threads to download]

    [本文链接] http://www.cnblogs.com/hellogiser/p/double-threads-to-download-and-write.html [题目] 网络上下载数据,然后 ...

  6. CI框架初探

    2014年7月3日 17:39:35 简易版: index.php->codeIgniter.php->找到控制器类文件并include->创建实例->执行成员函数 详细版本: ...

  7. codeforces 489C.Given Length and Sum of Digits... 解题报告

    题目链接:http://codeforces.com/problemset/problem/489/C 题目意思:给出 m 和 s,需要构造最大和最小的数.满足长度都为 m,每一位的数字之和等于 s. ...

  8. hdu 1050 Moving Tables 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1050 这道题目隔了很久才做出来的.一开始把判断走廊有重叠的算法都想错了.以为重叠只要满足,下一次mov ...

  9. rdesktop remember

    整个地球都知道rdesktop,有了它,我们可以从Solaris或者Linux使用Windows,当然Windows要开启Windows Terminal Service.虽然也有基于GTK+的tsc ...

  10. MVC登录案例

    1.在Controllers文件夹里面新建一个控制器HomeController;2.在默认的Index方法里面添加一个视图,名字跟Controller中的方法名一样叫Index,添加后的视图文件会在 ...