朋友推荐的一篇文章,讲明白了一些我们一直在用,但又很模糊的东西。翻译了一下,才发现,英语水平是硬伤啊。
横轴时间推移,纵轴技术演进,很可能在你发布一个app之后几个月一个新的android版本发布了。那么,这对你的app意味着什么,是否一切都要推翻了。
向前兼容性是Android的一项很具竞争力的技术-当用户使用新的android版本编译工程的时候,用之前版本编译过的工程依然坚挺。这就是compileSdkVersion, minSdkVersion, and targetSdkVersion引入的原因:这些变量分别控制着使用哪个版本的API,最低版本API,以及使用哪种兼容模式。
compileSdkVersion
compileSdkVersion 这个属性是你告诉Gradle 用哪个版本的sdk编译你的app。使用最新的android sdk 可以让你使用最新引入的APIs。
需要强调的是,改变compileSdkVersion不会影响运行时的行为(向下兼容)。当改变compileSdkVersion的时候,可能会出现新的警告或者错误,compileSdkVersion这个属性不会打包进你的apk,他只会在编译时期有效。(当然,你应该修改那些警告,Google不会无缘无故的更新一个API)。因此,强烈推荐使用最新版本的sdk。使用最新版本的编译检测,避免过时的API,使用最新API,这些会使你大受毗益。
有一点值得注意,使用Support Library的时候,使用最新的sdk编译才能引入最新的Support Library。举个例子,要使用23.1.1 Support Library,你必须使用的compileSdkVersion至少为23。总之,新的Support Library是伴随新的平台版本一起发布的,Support Library提供新的支持库来新增API以及新特性。
minSdkVersion
设置compileSdkVersion可以让你使用最新的APIs,minSdkVersion用以设置你的app的最低兼容版本。minSdkVersion是Google Play Store用以决定哪个设备可以安装你的app的一个标志。
在开发中,minSdkVersion也扮演着重要的角色:默认情况下,会在你使用高于minSdkVersion的API时给出警告,帮助你避免使用minSdkVersion这个版本不存在的API。使用仅存在于新版本中存在的APIs时,检查运行时的系统版本是一项常用的技术。
注意,你使用的一些库,例如一些Support Libraries或者Google Play services或许会自带minSdkVersion,你的app的minSdkVersion至少和这些库的最高的minSdkVersion一样高,举个例子,如果你的库指定的minSdkVersion分别为4,7,9那么你的app的minSdkVersion至少为9.在极少情况下,你需要继续使用库的minSdkVersion高于你的app指定的minSdkVersion(处理好各种边缘条件,让库版本中的API仅用于新的平台版本中),你可以使用tools:overrideLibrary marker(ps:猴子没用过,不知道怎么实现,目前也没遇到这等需求),特别注意,充分测试后才可使用。
当你选择minSdkVersion时,需要考虑Dashboards提供的分布图,他给你最近7天访问Google Play Store的设备版本分布–当你放一个app在Google Play Store上时,这些是你的潜在客户。是否要多支持3%的设备是否值得为他投入研发测试时间,保证用户体验,这是一个商业取舍。
当然,新的api是进入你app的关键,那么决定minSdkVersion就是一件简单的事情了。然而需要记住,14亿设备中,0.7%的比例也是很大一部分用户。
targetSdkVersion
这三个中,最有意思的当属targetSdkVersion。targetSdkVersion是Android提供的主要的向前兼容而不改变运行行为,除非targetSdkVersion改变了。这允许你先于行为改变之前使用新的APIs(如果你没有更新compileSdkVersion?)。
targetSdkVersion应用导致的很多的行为变化应该在VERSION_CODES中用明确的文档声明。但是所有的闪光点也应该列出来,突出这个版本的特点。
例如, Android 6.0改变了运行时权限模型,Android 4.4 通过set() and setRepeating()改变了警报集合的工作状态。
有一些行为的改变对用户来说有个明显的感知(menu按钮的弃用,运行时异常等),更新targetSdkVersion到最新版本应该是每个app最优先的事情。这并不意味着你要使用他的新特性,也不意味着你不用测试就更新targetSdkVersion。拜托,好好测试一下然后再更新targetSdkVersion,你的用户会因此而感谢你的。
Gradle and SDK versions
设置合理的compileSdkVersion, minSdkVersion,和targetSdkVersion 是很重要的。你可以想象一个在Gradle和Android Studio的世界里,这些属性通过集成你的模块的 build.gradle文件集成到了系统工具中(在Android Studio的工程结构中也可以看到)
android {
compileSdkVersion 23
buildToolsVersion “23.0.1”
defaultConfig {
applicationId “com.example.checkyourtargetsdk"
minSdkVersion 7
targetSdkVersion 23
versionCode 1
versionName “1.0”
}
}
compileSdkVersion,一个编译时的属性(谁也能猜到!),是android的伴随编译工具版本一起的一个属性。另外两个略有不同,他们是构建时期的属性 – 这些默认设置是所有构建变量的基础在这里你为他们设置默认值。但是你可以想象,在一个复杂的系统中,你的app特定的版本有不同的minSdkVersion。
minSdkVersion和targetSdkVersion区别于compileSdkVersion的另一个地方是,这两个属性将会打包进你的app中–如果你看一下生成的AndroidManifest.xml,你将会看到:
<uses-sdk android:targetSdkVersion=”23" android:minSdkVersion=”7" />
如果你手动改变manifest,你会发现,它会在构建app是自动给你忽略(虽然其他的系统依赖这个属性)。
综上所述
如果你了解了上面三个粗体的属性,你会发现这三个数值之间的关系:
minSdkVersion <= targetSdkVersion <= compileSdkVersion
This intuitively makes sense — if compileSdkVersion is your ‘maximum’ and minSdkVersion is your ‘minimum’ then your maximum must be at least as high as your minimum and the target must be somewhere in between.
这很直观,如果compileSdkVersion是最大值而minSdkVersion是最小值那么你的最大值至少在和你的最小值一样targetSdkVersion至少在最大和最小中间的某处。
更明智的,这三者之间的关系应该是这样
minSdkVersion (lowest possible) <=
targetSdkVersion == compileSdkVersion (latest SDK)
You’ll hit the biggest audience with a low minSdkVersion and look and act the best by targeting and compiling with the latest SDK — a great way to #BuildBetterApps.
你用低的minSdkVersion将会让你俘获更多的用户,用最新的targetSdkVersion和compileSdkVersion的外观和行为是你的app达到极致–一个构建良好app的必经之路。