转自:http://blog.sina.com.cn/s/blog_8984d3f301011pe4.html
一、需求描述
针对应用程序安装,各产品存在如下疑问:
1. 同一个手机,为什么恢复出厂设置后,在Settings->application中没有preferred Install Location的选项,但是在运行某一个apk(如packageInstaller)之后,在Settings->application中出现了preferred Install Location?
2. 不同apk,同一手机,为什么有的apk安装在SD卡上,有的apk安装在手机内?
3. 同一个apk,为什么有的产品安装在SD卡上,有的产品存在手机内?
4. 同一个apk,同一个手机,为什么有的时候安装在SD卡上,有的时候安装在手机内?
答案:以上现象在Froyo和Gingerbread上都是正常的,我们目前是follow的google原始设计,没有做过修改。原因详见代码分析。
二、分析
1、Settings中的安装位置
通过查看Froyo、Gingerbread版本的文件applicationSettings.java。发现在代码中定义了安装位置的设置功能,但是通过开关默认是关闭的(即默认不显示安装位置的设置菜单),可以通过设置Settings.Secure.SET_INSTALL_LOCATION 为1打开,打开后用户就可以改变应用程序安装的优选位置了。
在hw_default.xml中配置
settings.system.set_install_location
代码片段如下:
// Is app default install location set?
boolean userSetInstLocation = (Settings.System.getInt(getContentResolver(),
Settings.Secure.SET_INSTALL_LOCATION, 0) != 0);
if (!userSetInstLocation) {
getPreferenceScreen().removePreference(mInstallLocation);
} else {
mInstallLocation.setValue(getAppInstallLocation());
mInstallLocation.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = (String) newValue;
handleUpdateAppInstallLocation(value);
return false;
}
});
}
如图为默认用户可设置的配置:
public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
在hw_default.xml中配置
Settings.secure.default_install_location
2、不同apk,同一手机,为什么有的apk安装在SD卡上,有的apk安装在手机内
在Android 2.2中新的特性可以支持类似APP2SD卡上,我们的APK文件可以安装在SD卡上供用户使用
1. 首先让你的程序支持SD卡上安装必须具备设置API Level至少为8,即androidmanifest.xml的中android:minSdkVersion至少为8这样你的APK最终运行时兼容的固件只有2.2了,同时在androidmanifest.xml文件的根节点中必须加入android:installLocation这个属性,类似代码如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >
2. android:installLocation的值主要有preferExternal、auto和internalOnly这三个选项,通常我们设置为preferExternal可以优先推荐应用安装到SD卡上,当然最终用户可以选择为内部的ROM存储上,如果外部存储已满,Android内部也会安装到内部存储上,auto将会根据存储空间自适应,当然还有一些应用可能会有特殊的目的,他们一般必须安装在内部存储才能可靠运行,设置为internalOnly比较合适,主要体现在:
Services 服务
Your running Service will be killed and will not be restarted when external storage is remounted. You can, however, register for the ACTION_EXTERNAL_APPLICATIONS_AVAILABLE broadcast Intent, which will notify your application when applications installed on external storage have become available to the system again. At which time, you can restart your Service. Android123提示大家一般实时后台监控类的应用都应该装到内部存储,比较可靠。
Alarm Services 闹铃提醒服务
Your alarms registered with AlarmManager will be cancelled. You must manually re-register any alarms when external storage is remounted.
Input Method Engines 输入法引擎
Your IME will be replaced by the default IME. When external storage is remounted, the user can open system settings to enable your IME again.
Live Wallpapers 活动壁纸
Your running Live Wallpaper will be replaced by the default Live Wallpaper. When external storage is remounted, the user can select your Live Wallpaper again.
Live Folders 活动文件夹
Your Live Folder will be removed from the home screen. When external storage is remounted, the user can add your Live Folder to the home screen again.
App Widgets Widget
Your App Widget will be removed from the home screen. When external storage is remounted, your App Widget will not be available for the user to select until the system resets the home application (usually not until a system reboot).
Account Managers 账户管理
Your accounts created with AccountManager will disappear until external storage is remounted.
Sync Adapters 同步适配器
Your AbstractThreadedSyncAdapter and all its sync functionality will not work until external storage is remounted.
Device Administrators 设备管理器
Your DeviceAdminReceiver and all its admin capabilities will be disabled, which can have unforeseeable consequences for the device functionality, which may persist after external storage is remounted.
那么哪些应用适合安装在SD卡中呢? Android开发网建议一些占用资源比较大的游戏,比如大于3MB的单个文件,不需要长期驻留内存的应用,不具备提醒和实时监控的应用一般放到SD卡上比较合适,不过目前想让你的应用装到SD卡上,必须设置API Level至少为8以上,同时显示注明android:installLocation。在Android 2.2中新的特性可以支持类似APP2SD卡上,我们的APK文件可以安装在SD卡上供用户使用
3、同一个apk,为什么有的产品安装在SD卡上,有的产品存在手机内
这往往是因为apk中设置为auto,
有的产品默认在首选设置为“可卸载的SD卡”,当SD卡空间足够时,就会安装在SD卡上,如果SD卡空间不足时,会安装在手机内。
有的产品默认设为“设备内部存储”;只能装到设备内部了。
4、同一个apk,同一个手机,为什么有的时候安装在SD卡上,有的时候安装在手机内
这往往是因为apk中设置为preferExternal、auto,那么在首选设置为“可卸载的SD卡”或“由系统决定”时,SD卡空间足够时,就会安装在SD卡上,如果SD卡空间不足时,会安装在手机内。
现在又有个疑问了,如果apk设置和系统设置有冲突时如何取舍呢?
此处需要后续调试验证。
从Android系统2.2开始,允许应用程序安装在sdcard上。
应用程序APK
每个Apk的应用程序可以独立的设置该应用程序的安装目录
在应用程序的androidmanifest.xml文件的根节点中必须加入android:installLocation这个属性,类似代码如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android "
android:installLocation ="preferExternal"
... >
android:installLocation 的值主要有preferExternal、auto 和internalOnly这三个选项,通常我们设置为preferExternal可以优先推荐应用安装到SD卡上,当然最终用户可以选择为内部的 ROM存储上,如果外部存储已满,Android内部也会安装到内部存储上,auto将会根据存储空间自适应,当然还有一些应用可能会有特殊的目的,他们一般必须安装在内部存储才能可靠运行,设置为internalOnly比较合适,
在S8600和U8600上,我们在Setting --->Application
增加了一个首选安装位置的选项,在这里可以选择设备内部存储、可卸载sd卡,由系统决定等三个选项。。
现在发现有些apk在安装的时候,Setting --->Application-->首选安装位置, 选择的是优先安装在可卸载sd卡上,可是却安装在
系统中了,并且这些安装在系统中的应用,可以移动到sdacard上。
经过测试的结果如下:
应用程序APK | 系统的Application Settings | 安装后结果 |
无installLocation参数 | 可卸载sd卡 | 可卸载sd卡,可以移动 |
无installLocation参数 | 设备内部存储 | 设备内部存储,不可以移动 |
无installLocation参数 | 由系统决定 | 设备内部存储,不可以移动 |
auto | 可卸载sd卡 | 设备内部存储,可以移动 |
auto | 设备内部存储 | 设备内部存储,可以移动 |
auto | 由系统决定 | 设备内部存储,可以移动 |
internalOnly | 设备内部存储 | 设备内部存储,不可以移动 |
internalOnly | 可卸载sd卡 | 设备内部存储,不可以移动 |
preferExternal | 可卸载sd卡/设备内部存储 | 可卸载sd卡,可以移动 |
目前经过测试发现,在apk中如果声明为Auto,Setting --->Application-->首选安装位置, 选择可卸载sd卡
这样的应用程序最后被安装在 设备内部存储 中了,并且可以移动到sdcard上。
目前大多数应用都声明了auto,这样会造成很多应用程序在安装的时候无法安装到sdcard,而是直接安装到了系统中,只能通过移动至sdcard
才能把这些apk安装在sdcard上,我们手机的系统空间本来就不够,这样Auto的也无法直接安装到sdcard上。
四、结论
通过代码的分析,发现我们没有修改google原始设计,以上现象都是正常的。
文章转自:http://blog.sina.com.cn/s/blog_8984d3f301011pe4.html