我们先从一个实例开始
如图所示:当我们在build.gradle中设置minSdkVersion=8时,调用上诉API时会出现如图提示,无法运行在低于API8的手机上,这就是Android版本兼容性问题的体现;
下面是google官方给出的API平台版本:https://developer.android.google.cn/guide/topics/manifest/uses-sdk-element.html#provisional
下表列出了各 Android 平台版本支持的 API 级别。 如需了解有关运行各版本的设备的相对数量的信息,请参阅“平台版本”信息中心页面。
平台版本 | API 级别 | VERSION_CODE | 备注 |
---|---|---|---|
Android 7.0 | 24 | N |
平台亮点 |
Android 6.0 | 23 | M |
平台亮点 |
Android 5.1 | 22 | LOLLIPOP_MR1 |
平台亮点 |
Android 5.0 | 21 | LOLLIPOP |
|
Android 4.4W | 20 | KITKAT_WATCH |
仅限 KitKat for Wearables |
Android 4.4 | 19 | KITKAT |
平台亮点 |
Android 4.3 | 18 | JELLY_BEAN_MR2 |
平台亮点 |
Android 4.2、4.2.2 | 17 | JELLY_BEAN_MR1 |
平台亮点 |
Android 4.1、4.1.1 | 16 | JELLY_BEAN |
平台亮点 |
Android 4.0.3、4.0.4 | 15 | ICE_CREAM_SANDWICH_MR1 |
平台亮点 |
Android 4.0、4.0.1、4.0.2 | 14 | ICE_CREAM_SANDWICH |
|
Android 3.2 | 13 | HONEYCOMB_MR2 |
|
Android 3.1.x | 12 | HONEYCOMB_MR1 |
平台亮点 |
Android 3.0.x | 11 | HONEYCOMB |
平台亮点 |
Android 2.3.4 Android 2.3.3 |
10 | GINGERBREAD_MR1 |
平台亮点 |
Android 2.3.2 Android 2.3.1 Android 2.3 |
9 | GINGERBREAD |
|
Android 2.2.x | 8 | FROYO |
平台亮点 |
Android 2.1.x | 7 | ECLAIR_MR1 |
平台亮点 |
Android 2.0.1 | 6 | ECLAIR_0_1 |
|
Android 2.0 | 5 | ECLAIR |
|
Android 1.6 | 4 | DONUT |
平台亮点 |
Android 1.5 | 3 | CUPCAKE |
平台亮点 |
Android 1.1 | 2 | BASE_1_1 |
|
Android 1.0 | 1 | BASE |
Android版本更新,新的版本会引入一些新的特性和方法,新的方法带来很多便利,但是对系统版本有要求,无法再低版本手机上运行,如果未做兼容性处理,强行运行,会导致Crash。
做兼容性处理先要明白几个概念:
一:Android 中低端compileSdkVersion,minSdkVersion,targetSdkVersion,maxSdkVersion你弄明白了么!
新建一个项目工程时,系统都会默认为我们配置上面的参数,compileSdkVersion,minSdkVersion,targetSdkVersion,为什么设置这些参数,有什么作用,你都知道么!
1.1:compileSdkVersion
compileSdkVersion 26:指target=android-26,也就是{Sdk}\platforms\android-26\android.jar编译项目
在项目工程的External Libraries下可以看到
如果compileSdkVersion 修改为27,相应的也会做修改
在该API下有对应的API方法调用,如果版本过低,高版本的方法是没有导入,不可调用的!一般情况下,设置compileSdkVersion为最新的API即可,这也是项目默认的行为。
1.2:minSdkVersion
minSdkVersion 15,指app最小支持版本为API15(Android 4.0),低于Android 4.0的手机无法安装此类应用,当设置minSdkVersion 15时,已经完全覆盖100%的设备
并且google官方给出了其他最小版本对应的比例
minSdkVersion不仅在安装时起作用,在项目构建时也会起作用。如图,在minSdkVersion 8 调用API 9中的方法时给出提示
1.3:targetSdkVersion
targetSdkVersion 26,指当前应用已在API26(Android 8.0)经过测试,无需系统开启兼容模式保证程序正常运行。这个值一般和最新的API值相同。
当设置targetSdkVersion 26时会有如图提示,意思是没有设置为最新的API Level值,打开SDK manager看到最新的API Level为 27,将targetSdkVersion设置为27便兼容了最新的API
1.4:maxSdkVersion
maxSdkVersion 26 标明App最高应用版本为API 26(Android 8.0),高于Android 8.0的手机无法安装此类应用。如果系统升级后,高于maxSdkVersion ,应用将会被卸载。所以官方文档,不推荐使用这个属性。
二:针对API的变更引起的问题如何做兼容性处理呢?
1:在程序运行时对应用所运行的平台进行判断,旧平台使用旧的API,新平台使用新的API
使用高于minSdkVersion API Level的方法时,可以看到如下三条提示
1.1:使用TargetApi注解标注
注:targetApi,只屏蔽某一新API才能使用的方法报的Android lint错误,如图path.getTotalSpace,如果你在此方法中引入了另一个高于minSdkVersion的api时,此方法仍会报错!
1.2:使用SuppressLint注解标注
注:屏蔽一切新API才能使用新方法才报的Android lint错误
1.3:使用Build.Version
使用build.Version.SDK_INT运行时判断,分别处理
总结:1.1和1.1虽然未提示错误,但问题依然存在,我们一般结合1,3使用
二:用反射的方式调用高版本中的新功能接口进行调用
如果是基于低版本SDK开发,那么新版本中的新接口肯定编译不通过,这时候可以考虑反射的方式先去查找这个方法是否存在,如果有就代表用户的手机支持该调用方法,如果没有则采用低版本的处理方式(借用网上的一段话)
三:分离代码
分别在不同的SDK上编译运行,最后classLoader加载高版本中的相关类接口。此方法如同二,可以将高版本中的API接口封装后再高版本中的SDK编译成jar包,供低版本中动态加载(借用网上的一段话)
四:使用官方提供的support类库,如support-v4,support-v7,support-v13等