现在的位置: 首页 > 移动开发> 正文
Android 多APK设计专题之为不同的API Level创建不同的应用APK
2012年02月07日 移动开发 评论数 1 ⁄ 被围观 6,137+

training-prof

多APK支持是 Android Market 的一个新特性,它允许您为同一款应用对应不同的设备API Level 创建不同的APK,Android Market 会自动进行管理,通过识别用户设备的系统等级,比如2.2,2.3,4.0等等,然后会选择适合该设备的APK来让用户安装。

为不同的API Level设计的APK,可以进行特别的优化设置,比如GL纹理设置, API级别,屏幕尺寸,或其中的多个组合。

本节课就带领大家熟悉一下多APK的设计思路,您可以从中找到必要的开发工具和开发维护多个版本APK的方法。


确认您需要多个APKs

当您设计一款应用程序,为了满足多版本多设备之间的需求,在不牺牲向后兼容性的情况下,又可以利用最新版本的新特性,似乎多APK支持是个不错的解决方案。但事实并非如此,您可以通过阅读资料《Using Single APK Instead 》和《this article》来学习怎样在单一APK中实现上面提到的功能需求,以及怎样利用我们的支持库,同时也可以了解一下如何来编码实现。

使用单一APK有如下优势:

  • 发布和测试更容易
  • 只需要维护一个代码库
  • 应用程序能够自适应设备配置的变化
  • 应用恢复功能跨设备通用
  • 应用升级容易

本文的余下章节,假定您已经认为您确实需要多APKs的解决方案,而不使用单一 APK 的方法。

图示化需求

可以通过创建一个简单的图表来确定需要几个APK来支持,以及每个APK与之对应的API Level范围。您可以在Android 平台版本的信息页面(Platform Versions )中找到有用的参考资料,通过这种方法可以快速确定需要的APK个数和每个APK对应的API Level范围,尤其在出现API Level范围有重叠情况的时候更加有效,同时也方便了日后参考。

创建一个水平的列表来表示出当前已经发布的Android 版本号,在列表的最后一个位置放置一个+号来代表未来发布的版本。

3 4 5 6 7 8 9 10 11 12 13 +

对上面的列表进行着色,每一种颜色对应一个APK,之后您的团队就可以以此来进行讨论还开发。

3 4 5 6 7 8 9 10 11 12 13 +

设计公共库

无论是修改已有的代码做二次开发,还是从头开发一个新的应用,第一件事情就是提取公共的代码库,这些代码可以被不同的应用使用,并且只需要在一处编写和维护,比如多语言支持(language-localized strings),颜色主题(color themes),bug修复代码等,提供公共代码可以大大提高开发效率和节省开发时间,以及降低更新代码时引入的错误。

注:如何提取和创建公共的代码库,可参照下面的文章

  1. Setting up a library project (Eclipse)
  2. Setting up a library project (Command line)

如果您打算将已开发的单一APK转化为多APK支持,那么以下资源通常可以放置到公共代码库中,比如字符串资源文件(localized string file),常量值(list of values),颜色定义(theme colors),菜单图标(menu icons )和可共用的布局文件(layout )。或者,您打算从头开发一个应用,这时候也应该先开发公共的代码库,然后将各个APK不同的特定代码部分移动到具体的APK中,便于代码的管理和以后的扩展,当开发过一段时间之后,您可以逆向从各个不同的APK中再提取公共的部分来更新公共代码库。

建立工程项目

每一个独立的APK对应于一个独立的工程文件夹,为了方便代码的组织和管理,所有APK项目的工程文件夹和公共项目文件夹应该放在同一个根目录下面,并且所有的APK项目应该是相同的包名(package name)。示例代码展示了建立上面列举的3个独立APK的项目文件夹,组织结构如下:

   alexlucas:~/code/multi-apks-root$ ls
   foo-blue
   foo-green
   foo-lib
   foo-red

工程目录建立好以后,每个独立的APK项目都可以引用公共项目库,一般将启动Activity(starting Activity )放在公共项目库中,然后独立的APK工程中可以继承和扩展该Activity,这样便于将初始化代码集中在一个地方,例如 initializing Analytics, running licensing checks, and any other initialization procedures。

配置 Manifests 文件

当用户通过Android Market下载支持多APK的应用时,Market过滤器会依据如下的规则来选择合适的APK版本:

  • manifest 中声明的版本号必须匹配
  • manifest 中声明匹配的所有版本号中最大者优先

用我们前面讨论过的例子来进行说明,假如 manifest 中未设置支持的最大API等级(max API level) 选项,则每一个APK对应的API Level 如下:

3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +

minSdkVersion 越大则代表支持越高版本的代码,那么如上图 red ≥ green ≥ blue,则上图可以合并如下:

3 4 5 6 7 8 9 10 11 12 13 +

现在,假如 Red APK 使用了一种其他APK没有的新功能,比如前置相机,API Level 11以后支持。当用户设备通过Android Market进行程序下载的时候,Market Filters就会检测设备的信息,看是否是Level 11以上,是否有前置相机,如果不符合条件的话,Red APK就不会列在下载清单中,用户也就没法下载。事实上,目前仍有很多的设备还没有达到Level 11,也没有配置前置相机,那么如何解决此类问题呢。

幸运的是,Android Market会自动处理这种情况,它发现当前设备与Red APK的manifest 文件声明不符,会简单忽略它,然后继续检测Green APK,因为 Green APK没有设置maxSdkVersion 选项,本身又向前兼容,这样不管设备的版本是不是Level 11以上,也不管设备是否有前置摄像头,Green APK 仍然可用,用户也可以下载。

为了便于管理所有的APKs,应该合理设置版本号(version code scheme)。推荐阅读指南《Version Codes》,我们的例子中有3个独立的APK,每一个可以设置1000的版本号范围,前几位的数字(minSdkVersion )用来标志不同的APK,每次更新程序依次递增。示例如下:

   Blue: 03001, 03002, 03003, 03004...
   Green: 07001, 07002, 07003, 07004...
   Red:11001, 11002, 11003, 11004...

综合以上,您的 Android Manifests 文件可能如下:

Blue:

   <manifest xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"    android:versionCode="03001" android:versionName="1.0" package="com.example.foo">    <uses-sdk android:minSdkVersion="3" />    ... 

Green:

   <manifest xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"    android:versionCode="07001" android:versionName="1.0" package="com.example.foo">    <uses-sdk android:minSdkVersion="7" />    ... 

Red:

   <manifest xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"    android:versionCode="11001" android:versionName="1.0" package="com.example.foo">    <uses-sdk android:minSdkVersion="11" />    ... 

发布前的检测清单

在将您的应用发布到Android Market之前,请仔细检查下面清单中列举的项目。请记住这些检查只适用于多APKs的程序设计,本文无法列出要发布到Android Market程序的所有检测项目。

  • 所有的APKs拥有相同的包名
  • 所有的APKs必须使用相同的签名文件
  • 如果多个APKs的平台兼容版本有重叠,那么拥有较高minSdkVersion版本的APK必须拥有较高的版本号(version code)
  • 检查manifest配置文件中的filter,防止出现矛盾的地方(例如,APK声明为只支持屏幕类型为XLARGE的cupcake版本,那么此APK将不能被任何设备下载)
  • 每一个APK的manifest配置文件必须是唯一的,至少支持一种类型的屏幕,OpenGL纹理,或者Android固件版本
  • 每一个APK都至少在一个平台上做过测试,开发环境中可以建立多个不同类型自定义的模拟器,请尽量做完整的测试

利用 Aapt (the Android Asset Packaging Tool) 工具来做最后的打包和检查工作,有效防止意外的小错误导致您的应用无法在Android Market的下载清单中正常显示出来。

   >aapt dump badging
   package: name='com.example.hello' versionCode='1' versionName='1.0'
   sdkVersion:'11'
   uses-permission:'android.permission.SEND_SMS'
   application-label:'Hello'
   application-icon-120:'res/drawable-ldpi/icon.png'
   application-icon-160:'res/drawable-mdpi/icon.png'
   application-icon-240:'res/drawable-hdpi/icon.png'
   application: label='Hello' icon='res/drawable-mdpi/icon.png'
   launchable-activity: name='com.example.hello.HelloActivity' label='Hello' icon=''
   uses-feature:'android.hardware.telephony'
   uses-feature:'android.hardware.touchscreen'
   main
   supports-screens: 'small' 'normal' 'large' 'xlarge'
   supports-any-density: 'true'
   locales: '--_--'
   densities: '120' '160' '240'

仔细检查aapt工具的输出,看看有没有设置有矛盾的地方,尤其是关于支持的屏幕类型(supports-screens )和兼容的屏幕类型( compatible-screens),没有预期之外的多余的用户功能(uses-feature)权限,在上面的示例中,该APK在很多设备中都不可见。

什么原因导致的呢?因为上面的APK配置文件中加入了发信息(SEND_SMS)权限,android.hardware.telephony 特性就被隐式自动添加了。API 11 是Honeycomb (专门为平板设计的系统),而该设备没有支持电话的硬件(telephony hardware),Android Market就会将此APK过滤掉,导致 Honeycomb 设备没法下载和安装该APK,直到未来的设备APK Level升级,加入了支持电话的硬件,这个APK才能被下载安装。

幸运的是,我们可以只简单的修改一下配置文件即可解决这个问题:

   <uses-feature android:name="android.hardware.telephony" android:required="false" />

完成了以上的检查工作,提交APKs到Android Market。经过审核后,您就可以在Android Market中下载和安装这些应用到您的测试设备中,确保所有的APKs都正确匹配配置文件中声明的设备类型,APK在预期的设备平台上会正常工作,到此为止,恭喜您,多APK设计的工作就完成了。

参考文摘:

http://developer.android.com/training/multiple-apks/api.html

目前有 1 条留言 其中:访客:1 条, 博主:0 条

  1. 香袭人 : 2012年02月17日20:08:23  -49楼 @回复 回复

    博主,来看你了。

给我留言

留言无头像?


×
腾讯微博