targetSdkVersion、compileSdkVersion、minSdkVersion作用与区别

Android Studio 新建一个工程后,build.gradle里会有targetSdkVersion、compileSdkVerson、minSdkVersion这几个字段,这些配置有啥意义呢?

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.gui.gui.custom.view"
        minSdkVersion 26
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

minSdkVersion:

指定app运行的最低设备sdk版本,如minSdkVersion=19 表示该app最低支持Android 4.4(API 19)设备,低于此版本的设备将不能使用该app。随着Android系统版本的持续更新,之前旧的系统版本占有率越来越低,我们可以根据需要将minSdkVersion值往后调整。

compileSdkVersion:

和编译时有关。比如我们当前compileSdkVersion=28(Andorid 9.0),Android 10 新增了有关5G的api。我们的app想尽早使用5G相关的api,这时只需要将compileSdkVersion=29(Android 10),就能在编译阶段编译通过。此外,还需要注意的是,由于这个5G api是新增的,因此需要判断当前系统版本>=29才能使用新api。

targetSdkVersion

直观翻译是“目标版本”,它的作用是兼容旧的api,怎么理解呢?那就看看这个字段用在哪些地方。举个例子,Android 8.0/8.1 系统规定了透明的activity 不能固定方向,否则抛出异常。我们暂时不管google设计的目的何在,先想想假设我们的app使用了透明的activity,且固定了方向,在Android 8.0版本以下运行正常,当我们运行在Android 8.0/8.1系统上,结果如何会如何呢?很不幸,直接crash。对于我们来说,这结果当然不能接受了,我一个好端端的app,你升级个Android 系统直接让我的app挂掉,没有转圜的余地,不科学啊。因此,google想出了一个办法,那就是通过targerVersion字段来区分同一api在不同系统上的行为。我们来看看源码:

Android 8.0 Activity onCreate

从上图可以看出:getApplicationInfo().targetSdkVersion取的值即是在build.gradle里设置的targetSdkVersion值,这里判断targetSdkVersion是否大于Android 8.0(O),如果成立才执行后续逻辑(透明且固定方向),进而抛出异常。在此我们知道,想让这段逻辑不成立,那么我们将targetSdkVersion设置为26(Android 8.0 对应26)以下,即使我们app运行在Andorid 8.0以上的设备,都不会出现问题。这样,我们的app不更新,但是新的Android SDK 里Activity onCreate方法变更了部分逻辑行为,通过targetSdkVersion限制,我们的app依然能够以旧的逻辑运行新的设备上,达到了兼容老版本api的目的。
google建议:

    /**
     * The minimum SDK version this application targets.  It may run on earlier
     * versions, but it knows how to work with any new behavior added at this
     * version.  Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT}
     * if this is a development build and the app is targeting that.  You should
     * compare that this number is >= the SDK version number at which your
     * behavior was introduced.
     */
    public int targetSdkVersion;

大致意思就是:当我们更新targetSdkVersion时,比如从26(Android 8.0)变更到29(Android 9.0),意味着我们对26~29之间的系统兼容性进行了充分的测试,因此每当我们变更targerSdkVersion时,要充分测试其系统兼容性。
也许你会说,那我可以不更新targetSdkVersion值嘛,一劳永逸,理论上没啥问题。但是,如果你想在新的系统上使用api新的行为,那么就需要更新targetSdkVersion。再者,google会对targetSdkVersion进行一些强关联,比如app上传到google play,必须要求targetSdkVersion>=26。

到这,也许你还会说,为啥Andorid 6.0(包含)以上动态权限不根据targetSdkVersion来适配呢?我们说的targetSdkVersion是向前兼容,兼容之前的app使用的同一api旧的行为逻辑,而动态权限是google在Android 6.0(包含)以上强制要求的,人家就不想给你转圜的余地,有啥办法呢?还是乖乖判断当前系统是否是Android 6.0及其以上的,再决定是否动态申请权限了。。

三者联系

compileSdkVersion>=targetSdkVersion>minSdkVersion

扫描二维码关注公众号,回复: 8896073 查看本文章
发布了83 篇原创文章 · 获赞 4 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/GracefulGuigui/article/details/104095711