替不同的系统版本创建不同的apk程序(多apk的支持)

为不同的系统版本创建不同的apk程序(多apk的支持)

这篇文章是我在eoewiki上的翻译,如有不妥之处,请求提出您的宝贵建议或者建议。大家可以相互交流。

http://wiki.eoeandroid.com/Creating_Multiple_APKs_for_Different_API_Levels#.E5.8F.91.E5.B8.83.E5.89.8D.E7.9A.84.E6.A3.80.E6.9F.A5.28Go_Over_Pre-launch_Checklist.29

Creating Multiple APKs for Different API Levels

原文地址:http://docs.eoeandroid.com/training/multiple-apks/api.html 翻译:苏长利

目录

 [隐藏] 
  • 1 为不同的API版本创建不同的APK
    • 1.1 确认您是否需要多apk支持
    • 1.2 画出你的需求
    • 1.3 把所有的共用代码和共用资源放在同一个库工程里( Put All Common Code and Resources in a Library Project)
    • 1.4 创建新的APK工程(Create New APK Projects)
    • 1.5 调整Manifests文件(Adjust the Manifests)
    • 1.6 发布前的检查(Go Over Pre-launch Checklist)

[编辑]为不同的API版本创建不同的APK

为了在开发android应用程序的时候加以利用google安卓市场的多apk支持特性,刚开始就采取一些良好的措施去增加对多apk的支持,是非常重要的,这样可以在将来开发的过程中减少不必要的麻烦。这一节将向您展示如何为你的app创建多apk支持--不同的apk支持不同的api版本。还将获得一些维护多apk代码库尽可能的简单的工具。


[编辑]确认您是否需要多apk支持

当你试图创建一个支持跨多代android系统的应用程序时,很自然的你希望你的应用程序可以在新设备上使用新特性,并且不会牺牲向后兼容。刚开始的时候认为通过创建多个apk去支持多设备是最好的解决方案,但是往往不是这样。而是使用单个的apk去替代多个apk,开发指南中有去完成这个目标有用的信息,包括如何使用支持库的信息。还可以学习到如何写只能运行在特定api版本的代码的方法,而不去使用像反射这样的非常消耗资源的技术。

如果你能让你的应用程序只使用一个apk,将有如下几点好处:

*发布和测试简单
*只需维护一个代码库
*应用程序可以适应不同配置的设备
*App可以跨设备运行
*你不必考虑market的要求,apk的升级或者apk属于哪类设备

假设您已经研究了这个文档,已经学习了链接页面的内容,并且确定多apk支持的程序是你需要的,那么请继续看下面的小节。


[编辑]画出你的需求

首先创建一个简单的图表来快速确定你需要多少个APK, 每个Apk覆盖的API范围。为方便参考,Android开发者网站[平台版本页面]提供各个系统平台相对活跃的设备数量的分布数据。虽然刚开始听起来非常容易,但是每个pai版本的apk去实现目标有是比较困难的,特别是经常有重叠的部分。幸运的是,通过本方法,你会很容易绘制出你的需求,供以后开发参考。

为了创建你的多apk的需求,首先画一行表格代表各个android系统的api版本,在最后多画出一个格,代表将来的android版本。

3 4 5 6 7 8 9 10 11 12 13 +
3 4 5 6 7 8 9 10 11 12 13 +
接着是调整图表的颜色,一种颜色代表一个apk。下面的这个例子是每种颜色对应一个api版本范围。

一旦创建完这个图表,就分发给你的团队。这样项目团队成员之间的沟通就会变的非常简单了,为什么这么说呢,之前大家沟通都是问“为api3-api6创建的apk怎么样?除非大家知道这是android1.x中的一个,但是当api版本多了的时候怎么办?”,很明显,那样问可能大家都不知道说的是哪一个系统版本,有了这个图表之后,就可以简单的改问:“那个蓝色的apk怎么样?”,这样大家心里就很明白了;

[编辑]把所有的共用代码和共用资源放在同一个库工程里( Put All Common Code and Resources in a Library Project)

无论你是修改一个已经存在的Android应用程序还是开始创建一个新的程序,首先最重要的任务就是创建一个共用代码库(如标题所说的库工程)。把那些只需更新一次就可以减少项目的开发时间,减少项目错误的代码或者资源放进这个库工程里(比如可以放在代码库里的像本地化语言字符串,颜色主题,共用bug的修复等)。

注意: 如何创建库项目的细节,不是本节要讲解的范围,您可以通过下面的链接快速的了解如何创建库工程:

  • 创建库工程(在eclipse中)
  • 创建库工程(命令行)

如果你想把已有的应程序转成多apk的支持,需要重新组织你的代码中的所有的本地化字符串文件,值列表,颜色主题,菜单图标,布局文件,这些跨apk的不会改变的资源文件,并把他们放到库工程里。还有把那些不会改变太多的代码放到库工程里。这样你将会发现,你可以从一个apk继承另一个apk那些类的,扩展一到两个方法(函数)。

如果你刚开始创建一个新应用程序,首先要尽量在一个库工程中写代码,如果必要的情况下做成一个独立的apk。这样在以后长时间的开发过程中,长远看来是非常容易管理的,可以一点一点的添加共用代码和资源,并在数月之后指出这些代码或者资源在不经修改的情况下是否该移动到库里。

[编辑]创建新的APK工程(Create New APK Projects)

对于需要发布的每个APK,要分别为每个APK创建Android工程。为了便于管理,把库工程和所有相关的APK工程放在相同的父目录下,同时需要记住每个APK需要相同的包名,虽然他们在这个库里不必须去共享他们的包名。比如,如果你有3个APK,正如前面的规则所描述的,你的根目录会像这样:

alexlucas:~/code/multi-apks-root$ ls

foo-blue

foo-green

foo-lib

foo-red

一旦这个工程创建之后,把这个库工程引用到每个APK工程,如果可以的话,在库工程里定义启动Activity,并在APK工程里继承这个Activity。有了这个在库工程中定义的启动Activity,可以把你的所有应用程序的初始化工作放在一个地方,这样一来每个一个单独的APK就不需要重新实现这些像初始化分析,运行许可检查等其他的一些初始化工作,不用一个个APK的去写,维护起来也会简单好多。


[编辑]调整Manifests文件(Adjust the Manifests)

当用户从google安卓市场下载对多APK支持的程序时,正确的APK使用两个简单规则: 1.maifest已经展示这个APK是合格的 2.合格的APK有最高支持的Android API版本号

下面我们将以举例的方式讲解,首先,假设我们已经了解了前面所述的多APK的描述,并且没有为任何一个APK设定最高的API版本支持。
就每个apk单独来看,各个apk对应的版本号可能是这样: 

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 +
幸运的是,如果用户在google安卓市场使用这样的设备浏览软件的时候,安卓市场的引擎首先会到manifest文件里面去查看是否有要求的前置摄像头,如果没有将会被忽略掉,然后再查看red apk要求的api版本号和设备的api版本号是否匹配,只有这两个全匹配了才可以下载。绿色的pak不仅向前兼容到API11(只有在没有定义最大版本号的情况下才可以),并且不去检查设备是否有前置摄像头。这个app仍然可以从谷歌安卓市场上下载下来,因为仍有一个apk支持这个设备的API版本,并且这个apk也不要求设备必须有前置摄像头。因为它要求高于minSdkVersion,还需要高于minSdkVersion的代码,所以我们知道版本号的的大小排列是:red ≥ green ≥ blue.因此我们可以重叠起来看这三个图表,会变成如下图表:
3 4 5 6 7 8 9 10 11 12 13 +

现在我们进一步假设,红色的apk需要一些必须的东西,而其他的两种apk不需要有。goole安卓市场的开发者指南页面上列出了所有的可能过滤掉你的程序的罪魁祸首。为了更好的讲解例子,我们继续假设,红色的apk需要前置摄像头,但是实际上呢,红色apk有前置摄像头了,如果需要使用新功能,关键还需要的附加条件是必须在API11或者以上,但是并不是所有的设备都支持API11或以上系统版本,即使这个设备有前置摄像头也于事无补,是不是很恐怖。

为了把所有的apk分别处理,设定一个好的版本号使用规则特别重要,在开发者指南上有推荐的版本号规则Version Codes。咱们现在说的这个例子只涉及三个维度,用数字1000就足以把他们分别开,前面的两个数字代码区别特定apk的最低支持的版本号,支持不同的版本号只需要更改这个两个数字即可,如下所示:

Blue: 03001, 03002, 03003, 03004...

Green: 07001, 07002, 07003, 07004...

Red:11001, 11002, 11003, 11004...

这三种在程序的manifests文件中定义分别如下: Blue:

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

 

Green:

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

Red:

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

[编辑]发布前的检查(Go Over Pre-launch Checklist)

往google play上上传程序之前,一定要根据下面的条目仔细的检查下程序。记住,这些条目与多apk支持关系非常密,但是这里并没有列出所有的需要检查清单。

  • 所有的apk必须有相同的包名
  • 所有的apk必须用相同的数字证书签名
  • 如果apk有系统版本重合的地方,必须定义最低与最低版本号
  • 仔细检视manifest的过滤条件是否有冲突的地方(比如,一个apk只支持xlager的屏幕的设备,就不要被所有的设备看到)
  • 每一个apk的menifest必须至少支持一种屏幕,openGL texture或者系统版本。
  • 每一个apk至少在一个种设备上测试过。除非你是为定制的设备开发程序。

把程序提交到google市场之前,还要对编译过的程序进行检查,确保没有一些其他明显的问题而影响你的程序在google市场上被发现。使用aapt(Android Asset Packaging Tool,是生成和打包android应用程序的重要构建工具)这个工具进行编译检查特别的简单便利。

>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: '--_--'

当你在检查aapt的输出时,确保支持的屏幕和兼容的屏幕的值不冲突,不要在manifest中的"uses-feature"添加一些你并不需要的系统权限.如上面的例子,这个apk不会被很多的设备看到。

为什么呢?例子中显示,增加了SEND_SMS的权限要求,这个特征需要增加android.hardware.telephony硬件支持。从api11 Honeycomb开始是针对平板电脑的系统,没有打电话的硬件支持,Google play将会过滤掉不支持打电话的设备,只有API版本匹配,同时支持打电话的硬件支持才不会被过滤掉。

可以非常容易的在manifest中修复这个问题:

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

android.hardvare.touchscreen 权限要求也本不正确的加进去了,如果你想你的apk能被没有触碰功能的android系统的智能电视也能在市场上搜索到,进行如下设置:

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

当你完成了发布前的检查,你就可以向google play上提交你的apk了。发布完之后再去google play做最后一点检查,去上面搜索你的程序,下载下来,以确保你的目标设备可以搜到,并能使用。恭喜您,现在您已经完成了本节课程!!!