建立对两种以上屏幕尺寸的多apk支持(Creating Multiple APKs with 2+ Dimensions)
为了在开发android应用程序的时候加以利用google安卓市场的多apk支持特性,刚开始就采起一些良好的措施去增长对多apk的支持,是很是重要的,这样能够在未来开发的过程当中减小没必要要的麻烦。这一节将向您展现如何为你的app建立多apk支持--不一样的apk支持不一样的屏幕大小。还将得到一些维护多apk代码库尽量的简单的工具。android
确认您是否须要多apk支持
当你试图建立一个支持跨多android设备的应用程序时,很天然的你但愿你的应用程序能够在全部的设备上都看起来最好。你既想利用大屏幕的空间,也但愿能在小屏幕上运行,想利用新api的特征,也想在最新设备上的看到的纹理特征同时能在旧设备上一样能够看到。
刚开始的时候认为经过建立多个apk去支持多设备是最好的解决方案,可是每每不是这样。而是使用单个的apk去替代多个apk,开发指南中有去完成这个目标有用的信息,包括如何使用支持库的信息。还能够学习到如何写只能运行在特定api版本的代码的方法,而不去使用像反射这样的很是消耗资源的技术。api
若是你能让你的应用程序只使用一个apk,将有以下几点好处:app
- * 发布和测试简单
- * 只需维护一个代码库
- * 应用程序能够适应不一样配置的设备
- * App能够跨设备运行
- * 你没必要考虑market的要求,apk的升级或者apk属于哪类设备
假设您已经研究了这个文档,已经学习了连接页面的内容,而且肯定多apk支持的程序是你须要的,那么请继续看下面的小节。eclipse
画出你的需求
首先建立一个简单的图表来快速肯定你须要多少个APK, 每一个Apk覆盖的屏幕尺寸范围。虽然刚开始听起来很是容易,可是每一个pai版本的apk去实现目标有是比较困难的,特别是常常有重叠的部分。幸运的是,经过本方法,你会很容易绘制出你的需求,供之后开发参考。让咱们先讨论一下如何根据屏幕尺寸和api版本,为apk划分对应的设备范围。首先是建立一个图表,行和列对应一个值,而且都用颜色填充,每种颜色表明一个apk。ide
上面的例子有四个apk,蓝色的是为全部的small/normall屏幕设备的开发的,绿色的是为全部的large屏幕设备开发的,红色的是为xlarge设屏幕设备开发的,这三种apk对应的API范围是3-10。紫色的是一个特例,它能够适应全部的屏幕大小,可是仅支持API11或者以上系统。更重要的一点是,当你瞅一眼这个图表的时候,你能快速的看出来哪一个apk对应什么API,对应什么屏幕大小。此外你还能够为每个apk起一个很是拉风的开发代号。当咱们的团队成员问咱们,“咱们是否是该测试红色的那个apk了”,而不是说“咱们是否是该测试这个支持API3-10,支持xlarge屏幕,而且不是在摩托的Xoom平板上的apk了”,显然,前一种方式更容易理解。还有,把这个需求图表打印下来,分发给每个团队成员。函数
把全部的共用代码和共用资源放在同一个库工程里( Put All Common Code and Resources in a Library Project)
不管你是修改一个已经存在的Android应用程序仍是开始建立一个新的程序,首先最重要的任务就是建立一个共用代码库(如标题所说的库工程)。把那些只需更新一次就能够减小项目的开发时间,减小项目错误的代码或者资源放进这个库工程里(好比能够放在代码库里的像本地化语言字符串,颜色主题,共用bug的修复等)。工具
注意: 如何建立库项目的细节,不是本节要讲解的范围,您能够经过下面的连接快速的了解如何建立库工程:布局
若是你想把已有的应程序转成多apk的支持,须要从新组织你的代码中的全部的本地化字符串文件,值列表,颜色主题,菜单图标,布局文件,这些跨apk的不会改变的资源文件,并把他们放到库工程里。还有把那些不会改变太多的代码放到库工程里。这样你将会发现,你能够从一个apk继承另外一个apk那些类的,扩展一到两个方法(函数)。学习
若是你刚开始建立一个新应用程序,首先要尽可能在一个库工程中写代码,若是必要的状况下作成一个独立的apk。这样在之后长时间的开发过程当中,长远看来是很是容易管理的,能够一点一点的添加共用代码和资源,并在数月以后指出这些代码或者资源在不经修改的状况下是否该移动到库里。
建立新的APK工程(Create New APK Projects)
对于须要发布的每一个APK,要分别为每一个APK建立Android工程。为了便于管理,把库工程和全部相关的APK工程放在相同的父目录下,同时须要记住每一个APK须要相同的包名,虽然他们在这个库里没必要须去共享他们的包名。好比,若是你有4个APK,正如前面的规则所描述的,你的根目录会像这样:
1 2 3 4 5 6 7 8 9 10 11 |
alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-purple
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支持全部的屏幕尺寸,而不是仅仅只支持目标尺寸的屏幕,让咱们从新看一下前面的表格:
Since it’s okay for coverage to overlap, we can describe the area covered by each APK like so:
由于他们有重合的部分,咱们能够像下面同样去描述每一个apk
-
- 蓝色的覆盖全部的屏幕尺寸,最低支持sdk是3
-
- 绿色的覆盖大屏幕或者更大的屏幕,最低的sdk是3。
-
- 红色的覆盖的是超大屏幕的(日常的平板),最低支持sdk9
-
- 紫色的覆盖全部的屏幕尺寸,支持最低sdk11
请注意,在上述的规则中有不少重合的地方。举个例子,一个xlarger屏幕的设备,系统版本是API11,这个4个apk全均可以在这个设备上运行,咱们根据最高版本优先被搜到的原则,咱们能够把他们的优先级列出来:
紫色 ≥ 红色 ≥ 绿色 ≥ 蓝色
为何容许重叠呢?
如今咱们进一步假设,紫色的apk须要一些必须的东西,而其余的两种apk不须要有。google安卓市场的开发者指南页面上列出了全部的可能过滤掉你的程序的罪魁祸首。为了更好的讲解例子,咱们继续假设,紫色的apk须要前置摄像头,关键点就在于,必需要求有前置摄像头,可是并非全部的API11或以上设备上都配有前置摄像头,是否是很恐怖。
幸运的是,若是用户在google安卓市场使用这样的设备浏览软件的时候,安卓市场的引擎首先会到manifest文件里面去查看是否必需要有的前置摄像头,若是必需要求有前置摄像头,由于紫色的apk和设备不匹配,这个紫色的apk将会被忽略掉;而后再查看红色的apk,由于红色的apk即支持xlarger屏幕,对前置摄像头也没有硬性的要求,google play会认为红色的apk能够和设备匹配,程序就能够从google play上下载下来试用了,由于至少有一个支持这个设备的apk。
为了把全部的apk分别处理,设定一个好的版本号使用规则特别重要,在开发者指南上有推荐的版本号规则Version Codes。这一部分仍是比较值得阅读的,基本要点是为一组apk设定规则,咱们用两个数字表明最低支持的系统版本号,用两个数字表明支持的最大或者最小屏幕大小,另外的三个数字表明本身的程序的版本。经过这种方式,当设备的系统升级的时候,好比从10升级到11,apk升级的时候,在全部的apk中,优先被升级的apk是当前安装在设备上的那个apk。下面是一个版本号使用规则的一个例子,能够定义成以下格式,
蓝色: 0304001, 0304002, 0304003...
绿色: 0334001, 0334002, 0334003
红色: 0344001, 0344002, 0344003...
紫色: 1104001, 1104002, 1104003...
这三种在程序的manifests文件中定义分别以下:
蓝色:
1 2 3 4 5 6 7 8 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="0304001" android:versionName="1.0" package="com.example.foo">
<uses-sdk android:minSdkVersion="3" />
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true" />
...
|
绿色:
1 2 3 4 5 6 7 8 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="0334001" android:versionName="1.0" package="com.example.foo">
<uses-sdk android:minSdkVersion="3" />
<supports-screens android:smallScreens="false"
android:normalScreens="false"
android:largeScreens="true"
android:xlargeScreens="true" />
...
|
红色:
1 2 3 4 5 6 7 8 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="0344001" android:versionName="1.0" package="com.example.foo">
<uses-sdk android:minSdkVersion="3" />
<supports-screens android:smallScreens="false"
android:normalScreens="false"
android:largeScreens="false"
android:xlargeScreens="true" />
...
|
紫色:
1 2 3 4 5 6 7 8 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1104001" android:versionName="1.0" package="com.example.foo">
<uses-sdk android:minSdkVersion="11" />
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true" />
...
|
注意一下,在技术上,一个apk要么有支持的特定屏幕的标记,要么有兼容性的屏幕的标记,支持的屏幕是优先考虑的。可是若是同时有这两个标记是很很差的作法,这样会增长额外的复杂性,增长机会性错误。同时还要注意,不要使用默认的值(small和normal默认状况下老是true),在manifesets中应该明确指定屏幕大小的值。这样会减小之后的麻烦---顺便举个例子,manifest的目标sdk要求小于9,若是使用默认值,xlarge自动设置为false,xlarge的屏幕将不会支持,所以最好要明确指定。
发布前的检查(Go Over Pre-launch Checklist)
往google play上上传程序以前,必定要根据下面的条目仔细的检查下程序。记住,这些条目与多apk支持关系很是密,可是这里并无列出全部的须要检查清单。
- * 全部的apk必须有相同的包名
- * 全部的apk必须用相同的数字证书签名
- * 若是这些apk有系统版本重合的地方,最低系统版本号最大的那个apk必须有一个更高版本号(If the APKs overlap in platform version, the one with the higher minSdkVersion must have a higher version code)
- * 任何一种你将有支持的屏幕大小都要在manifest中设置成true,若是不想支持的就设置成false。
- * 仔细检视manifest的过滤条件是否有冲突的地方(好比,一个apk只支持xlager的屏幕的设备,就不要被全部的设备看到)
- * 每个apk的menifest必须至少支持一种屏幕,openGL texture或者系统版本。
- * 每个apk至少在一个种设备上测试过。除非你是为定制的设备开发程序。
把程序提交到google市场以前,还要对编译过的程序进行检查,确保没有一些其余的明显的问题而影响你的程序在google市场上被发现。使用aapt(Android Asset Packaging Tool,是生成和打包android应用程序的重要构建工具)这个工具进行编译检查特别的简单便利。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
>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的输出时,确保支持的屏幕和兼容的屏幕的值不冲突,不要在manifest中的"uses-feature"添加一些你并不须要的系统权限.如上面的例子,这个apk不会被不少的设备看到。
为何呢?例子中显示,增长了SEND_SMS的权限要求,这个特征须要增长android.hardware.telephony硬件支持。从api11 Honeycomb开始是针对平板电脑的系统,没有打电话的硬件支持,Google play将会过滤掉不支持打电话的设备,只有API版本匹配,同时支持打电话的硬件支持才不会被过滤掉。
能够很是容易的在manifest中修复这个问题:
1 |
<uses-feature android:name="android.hardware.telephony" android:required="false" />
|
android.hardvare.touchscreen 权限要求也本不正确的加进去了,若是你想你的apk能被没有触碰功能的android系统的智能电视也能在市场上搜索到,进行以下设置:
1 |
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />v
|
当你完成了发布前的检查,你就能够向google play上提交你的apk了。发布完以后再去google play作最后一点检查,去上面搜索你的程序,下载下来,以确保你的目标设备能够搜到,并能使用。恭喜您,如今您已经完成了本节课程!!!