在使用adb安装Apk时设置

adb install命令:

adb install [-l] [-r] [-s] <file>

概述: 将apk文件拷贝到设备并安装。 选项参数:

  • -l means forward-lock the app
  • -r 重新安装,保持程序数据
  • -s 安装到尾部存储

在使用adb设置默认安装位置

Android 2.2开始系统提供了软件可以装到到SD上的支持,对于adb命令而言也有了改进,Android 2.2开始pm命令支持安装选项参数:setInstallLocation,可以用adb通过shell执行pm设置一些参数,命令如下:

adb shell pm setInstallLocation option
  • 最后一个参数option为0:代表auto自动,Android系统会自动选择,
  • 最后一个参数option为1:代表默认安装到手机内部存储
  • 最后一个参数option为2:代表默认安装外部存储

在APK包中设置

在Android文档的App Install Location里面提到: 自API Level 8开始,可以允许应用安装至扩展存储(例如,SD卡)。这是一个可选功能,可以在应用的manifest属性的 android:installLocation里设定。如果没有设定这个属性,那么应用将被安装到内置存储,而且将不允许移动到扩展存储上。 为了允许系统可以在扩展存储上安装的你的应用,需要修改manifest文件,在 <manifest> 元素中包含android:installLocation 属性,设置其值为”preferExternal” 或 “auto”。例如:

<?xml version="1.0" encoding="utf-8"?>
<manifest android:installLocation="auto" ...> 
    <application ...>
        <activity ...>
        ...
        </activity>
        ...
    </application>
    ...
</manifest>
  • 如果定义了 “preferExternal”,意味着要求应用安装至扩展存储,但是系统不能保证应用肯定要安装至扩展存储。如果扩展存储没有空间了,系统将把应用安装到内置存储。用户可以在两个位置之间移动该应用。
  • 如果定义 “auto”,表示应用可能会安装在扩展存储,但是对安装位置没有特别的偏好。系统将基于很多因素决定该应用安装到哪里。用户同样可以将应用在两个位置之间移动。
  • 如果定义 “internalOnly”,表示应用被指定安装在内部存储上,用户不可以将应用移动到外部存储上。

向后兼容

将应用安装至扩展存储的功能是运行API Level 8(Android 2.2)及以上版本的设备才有效的。使用API Level 8 之前的版本编译的应用,将一直安装在内置存储,并且无法移动至扩展存储(即使设备上运行的是API Level 8版本的系统)。但是如果该应用计划支持低于8的API Level,则可以选择针对API Level 8及更高版本支持此特性,并且继续保持与低于API level 8的设备兼容。

允许安装在扩展存储并且保持与API Level 8或更低版本兼容:

  1. 在<manifest>元素中,包含值为”auto” 或 “preferExternal” 的 android:installLocation 属性。
  2. 保持android:minSdkVersion 属性不变(小于8的值)并且确定该应用代码只使用了与此level保持兼容的API。
  3. 编译应用,更改build target为API Level 8。这步操作是必须的,因为之前的Android库无法理解 android:installLocation 属性。

当应用安装到API Level低于8的设备上时,android:installLocation 属性被忽略,并且应用会被安装至内置存储上。

尽管xml标签这个将被之前的平台忽略,但还是要小心不要使用API Level 8中的编程API,除非在代码中提供向后兼容。

应用已经安装在扩展存储上时的特性

  • 只要扩展存储已经挂载在设备上,对应用的性能都没有影响。
  • .apk文件会保存在扩展存储上,但是所有的用户私有数据,数据库,优化过的.dex 文件和释放的原生代码都保存在内置存储空间上。
  • 存储应用的唯一容器是被一个随机生成的KEY加密存放的,仅仅能被最初安装的设备进行解密操作。因此,安装在SD卡上的应用仅仅针对一个设备可以工作。
  • 用户可以通过系统设置移动应用到内置存储。

当用户启用USB大容量存储以共享文件给计算机或者通过系统设置卸载SD卡,外置存储从设备卸载并且所有运行在外置存储的应用立刻都被结束。

不应当安装在扩展存储的应用

当用户启用USB大容量存储来给他们的计算机共享文件时(卸载或移除扩展存储),任何安装在扩展存储上并正在运行的应用都会被结束。此时系统并不知道应用程序的存在,直到大容量存储关闭,或者扩展存储重新挂载到设备上。
除了杀死该应用程序使它对用户不可用,它还会使用更严重地方式中断某些类型的应用程序。为了使应用始终如所期望的那样运行,当使用了下面任何一种特性,那就不应当允许该应用安装到扩展存储上去,以避免产生当扩展存储被卸载时所导致的后果。

Services

当扩展存储被卸载时,正在运行的Service将被结束并且不会再重新启动。可以注册 ACTION_EXTERNAL_APPLICATIONS_AVAILABLE broadcast Intent,当安装在扩展存储上的应用对系统重新有效时,会通知该应用。在那个时候,可以重新启动该Service。

Alarm Services

注册到AlarmManager的闹钟会被取消。当扩展存储重新挂载时,必须手工重新注册。

Input Method Engines

外部存储中正在使用的输入法将被替换为默认输入法。当扩展存储重新挂载,用户需要打开系统设置以重新启用该输入法。

Live Wallpapers

外部存储中正在运行的Live Wallpaper 会被替换为默认的。当扩展存储被挂载时,用户需要重新选择Live Wallpaper。

Live Folders

Live Folder将被从home屏幕移除。当扩展存储被挂载上时,用户可以重新添加Live Folder到Home界面。

App Widgets

App Widget 将被从Home界面移除,当扩展存储被挂载时,在系统重置Home应用之前,用户将无法使用该App Widget(通常直到系统重启)。

Account Managers

在扩展存储被挂载之前,应用程序使用AccountManager创建的账户都是不可见的。

Sync Adapters

在扩展存储被挂载之前,AbstractThreadedSyncAdapter 和所有相关的同步功能将无法工作。

Device Administrators

DeviceAdminReceiver 和它的管理能力会被禁止,这会导致设备功能产生无法预料的结果,这种现象会持续到扩展存储重新挂载为止。

Broadcast Receivers listening for "boot completed"

系统是在扩展存储挂载到设备前发送ACTION_BOOT_COMPLETED广播的 。所以如果应用安装到扩展存储上,它永远也接收不到这个广播。

如果应用使用的上面列表中的任何一种特性,那就不应该允许该应用安装到扩展存储上去。默认情况下,系统将不允许应用安装至扩展存储,所以不需要担心已存在 的应用。然而,如果不确定应用是否永远不会安装到扩展存储上去,那么可以通过定义 android:installLocation值为”internalOnly”来确保其安装至内置存储。