解析 Android 开发时的 SDK 版本参数设定

在开发 Android App 时,开发人员最容易出现困惑的地方之一应该是 compileSdkVersion、minSdkVersion 和 targetSdkVersion 这些参数的用途。对此,有 Google 内部的 Android 开发人员就这个议题写了一篇文章:Picking your compileSdkVersion, minSdkVersion, and targetSdkVersion。在这里会用不同的角度来说明这些参数的用途,希望能对大家在理解上有所帮助。

buildToolsVersion

首先,这是在那篇文章中没有说明到的另一个与版本有关的参数。这个参数主要是用来指定用哪一组编译程序来将你所编写的 Source Code 转成操作系统可以载入的形式,也就是产出 Apk。所以 Build Tools 在概念上可以看成是 Android Studio 的一部份或是其中一个套件,只是同时会有好几组。

譬如说要修理车辆,每一组的 Build Tools 就像是有人把修车的工具,扳手、起子、套筒之类的放在一个包包里。只是随着工具设计的翻新,包包里的工具可能会做调整,像是起子原本是各尺寸一只,现在可能改成只有一只但可以换各种尺寸的头。同样是拿来修车,工具也一样,但是为了区别内容物的不同所以给了不同的编号。

选用哪一组 Build Tools 原则上不会有太大的差异,大概就是编译的效能、产出的文件大小等等的细节。但有时候还是可能会牵涉到 Apk 内容或结构的问题影响运行,仍然要多注意改版的资讯。最保险的做法还是让 buildToolsVersion 的主版本编号与 compileSdkVersion 同步。

compileSdkVersion

compileSdkVersion 则是 Build Tools 在进行编译时,检查源代码在呼叫 SDK 所使用的规格是否正确的基准,但所指定的 SDK 并不会被编入 Apk 中。Google 会在发行新版系统时对 SDK 做调整,为了保持相容性,在规格上不太可能采取激进的方式,例如:同样名称的函式改为不同的参数规格。最常出现的大概就是在函式上标注 @Deprecated,等系统发行过几个版本之后再正式废止。

buildToolsVersion 及 compileSdkVersion 顾名思义就是在编译、生成时期所使用的工具,这句话的重点是编译过了、顺利产出 Apk,不代表运行上就没有问题,而且所谓的运行还要细分是在哪个版本上运行。因为 SDK 不是包含在 Apk 里,是包含在 Android 的系统之中。Apk 在哪一个版本的 Android 中运行,调用的就是对应版本的 SDK。所以运行调用叫会不会报错,跟编译会不会成功是没有直接的关连,除非运行的环境和 compileSdkVersion 指定的版本相同,但也仅限于规格的部份。

用旅游来做例子,Build Tools 就好像旅行社,把你对旅游的构想转成实际的行程。而 Compile SDK 则是旅行社在行前检查所使用的检查表,用来确认在行前是不是有什么细节遗漏了。选用哪一个旅行社对于规划行程没有什么太大的差别,顶多只是能够提供服务的多寡或细致的程度。而行前检查表如果用错了版本就有可能会出问题,像是要去的目的地签证条件改变了,旧的版本没有列上去,在行前检查时一切没问题,到了当地才发现没有办法入境,于是整个行程就报销了。但如果是用新的检查表,就可以在行前发现问题,并且做出补救的措施,确保行程能够如计划进行。

由于 Google Play 只限制 App 可运行的 SDK 最低版本,并没有限定最高的版本。也就是,使用者可以在硬体厂商有提供更新的情况下不断地升级系统版本,而 App 则会一直保持在可安装的状态下。如果一直不更动 compileSdkVersion,则有一些变动在编译时期不会被发现,前段提到的标注 @Deprecated 就是一例。前几次的系统版本更新在运行 App 上可能不会有问题,但是一旦真的有函式被废止了,则要到运行时才能发现,这时要侦错就不是件容易的事。但如果是使用新的 compileSdkVersion,则是在编译时就会有对应的讯息供作参考。

所以在开头提到的文章中有一个很重要的关键点是:当编译的结果还存有警告时,一定要进行对应的处理,这些警告的设计是有其作用的。

targetSdkVersion

在推出新的 Android SDK 版本有函式的行为新旧版本不一致时,为保持相容性,旧的行为会被保留,并且会以 targetSdkVersion 的值来判断要运行哪一种行为。以开头提到的文章中举例的 AlarmManager#set 来说,依官方文件的说明,Android 4.4 (API 19)以后使用的是不精确的时间,以减少设备被唤醒的次数及降低电量的耗损。官方文件中的另一段注解文字说到:targetSdkVersion 小于 API 19 的会继续之前旧的行为,也就是 SDK 中会判断 targetSdkVersion 的资讯来决定运行的源代码内容。

以前段提到旅游的例子来说,当实际出发到了当地的海关,targetSdkVersion 的规则就如同海关柜台人员不是一体套用新的签证规则,而是会好心地依照填写的申请日期决定适用的签证规则。如果填的是新规则公布之后的日子,代表填写的人应该知道新的签证规则,所以当然就照新的签证规则来审核。相对地,填写的日期在新规则公布之前的日子,则会使用旧的签证规则来审核。

Android 透过这种方式让 App 在新的系统版本中不会有预期之外的行为出现,即便 Google 打算在新版本中改变原本的行为。所以 targetSdkVersion 主要的用途是让开发者告知 SDK,开发者所认知的函式行为应该是哪一种,如果 targetSdkVersion 是设定成改变之前的值,则 SDK 会运行旧的版本,否则就运行新的。对开发者来说,修改 targetSdkVersion 后代表的意义是:开发者已经知道了新的 SDK 行为,并且确认这个行为是 App 所需要的。所谓的确认通常指的是要在参数指定之对应版本的运行环境中做过测试,而不光只是编译成功。

依照以上的说明,如果在更换了 targetSdkVersion 内容,却还是使用万年的模拟器设定来进行测试,以致模拟器上系统的版本一直没换,这时就有必要重新检讨开发时的测试策略了。

minSdkVersion

最直接的用途就是要求 Google Play 设定 App 可被安装的系统版本最底限,在这个版本之后的则不会被限制。

对开发者来说有另外一个要观注的重点和 targetSdkVersion 一样,minSdkVersion 也具有相同的意义。试想有一个 App 是在 Android 4.4 (API 19)开发的,预期的是 AlarmManager#set 的新行为,但是当 minSdkVersion 的值比 API 19 小时,程式运作在 API 18 以下的环境中一定没有 AlarmManager#set 的新行为,这时 App 会产生什么结果?

如果是上架很久的 App,源代码应该也是对应着系统版本演进的历程做修改。所以源代码中或多或少都有包含先前所提到和 SDK 类似用系统版本来判断程式要运行的新、旧逻辑区块,以适应各种不同版本的系统。在这种情况之下,minSdkVersion 理所当然的可以是很早期的版本数值。

如果是新开发的 App,因为没有经历过这些过程,所以 targetSdkVersion 和 minSdkVersion 在开发初始的阶段里意义上是一样的,这时对 minSdkVersion 调整最保守的做法应该是逐次逐版地往前调。当 minSdkVersion 的数值逐版向前调整时,也应逐版在对应的环境中做过测试,确保程式在旧行为下所呈现的结果也符合预期,并且在必要时要加上对新旧版本的判断式、补上合于旧版环境的源代码。

就像开头提到的文章中所指出,即使 14 亿台设备中的 0.7% 也是逼进一千万台可观的数字,如果不想放弃这样的商机,在砸了自己的招牌之前,还是乖乖地每一个版本确实地做好测试,否则宁可不要轻易地下调 minSdkVersion。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容