Android项目该如何选择targetSdkVersion

本文详细解析了Android开发中的targetSdkVersion选择策略及其与其他版本属性的关系,通过实例阐述了不同API版本对应用行为的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

新手的第一个Android项目或许没有认真考虑过如何选择targetSdkVersion的问题,也或许还有一部分像TeachCourse一样的开发者,积累一些工作经验后才回头来思考这个问题。那么该如何选择一个targetSdkVersion的属性值?一个属性值为23的targetSdkVersion表示什么含义?那么API 24和Android 7.0又是什么关系?为什么API 19开发的Android项目可以在Android 7.0系统的手机上运行,反之Android 4.x系统的手机可以运行API 24开发的Android项目?最后,正确理解compileSdkVersion、minSdkVersion和targetSdkVersion三者之间的关系。

应用程序接口和Android系统关系

一、认识targetSdkVersion

targetSdkVersion即目标软件开发版本,在创建每一个Android项目的时候都需要选择targetSdkVersionminSdkVersion,一个targetSdkVersion的属性值表示创建的Android项目使用哪个API版本,一个API版本使用一个整型数字表示,API的全称是Application Programming Interface,即应用程序编程接口,API 19对应的编程接口和API 23定义的编程接口存在差别,因为使用整型数字表示targetSdkVersion的属性值,容易记忆和便于比较它们之间的大小,高版本API编程接口可以兼容低版本API编程接口,反之则不行。

需要区别Android 7.0API 24之间的关系,Android 7.0定义的手机系统的版本,该系统的版本对外开放的应用程序接口被定义为API 24,如果开发者想要在开发的APP中使用Android 7.0系统提供的功能,这些功能包括:多窗口支持、通知显示变更、JIT/AOT编译、快速的应用安装路径等等,那么新手在创建的Android项目的时候就需要选择API 24的应用程序接口。

不知道开发者也没有注意到,为什么API 19开发的Android项目可以在Android 7.0系统的手机上运行,反之Android 4.x系统的手机可以运行API 24开发的Android项目,它们运行的效果是否一样呢?如果是Android 7.0系统运行API 24开发的应用程序,效果又是怎么样?这就让TeachCourse联想到了API 23开发的应用程序在低于Android 6.0系统上运行时,如果权限被禁用后,会提示如下图:

运行时权限

但是,如果API 23开发的应用程序在高于或等于Android 6.0系统的手机上运行时需要自己定义打印上述Toast,下面是完整的运行时权限申请的代码:


    private static final int REQUEST_CODE_PERMISSION=0x112;
    private void initPermission() {
        int flag= ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
        if(PackageManager.PERMISSION_GRANTED!=flag){
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA}, REQUEST_CODE_PERMISSION);
        }else{
            alterImageNew();
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (REQUEST_CODE_PERMISSION==requestCode){
            switch (grantResults[0]){
                case PackageManager.PERMISSION_DENIED:
                    boolean isSecondRequest=ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.CAMERA);
                    if(isSecondRequest)
                        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},REQUEST_CODE_PERMISSION);
                    else
                        Toast.makeText(this, "拍照权限被禁用,请在权限管理修改", Toast.LENGTH_SHORT).show();
                    break;
                case PackageManager.PERMISSION_GRANTED:
                    alterImageNew();
                    break;
            }
        }
    }

如果需要显示类似于上面图片显示的Toast提示,开发者需要在onRequestPermissionResult回调方法中,打印拍照权限被禁用,请在权限管理修改这句话,在使用API 23应用程序编程接口开发的APP中都可以反复复制上面代码,仅将CAMERA替换成定义的权限参数,将alterImageNew()替换成拥有权限后要执行的代码。

举这个例子的目的,想要说明为什么在API 23版本开发的APP在低于Android 6.0系统不会执行上述代码的原因。

高版本的API定义了一些的编程接口,但是通常不需要开发者考虑是否高版本API开发的APP在低版本的Android系统的兼容性问题,APIAndroid系统是两个不一样的概念,API属于应用层的东西,Android系统属于底层的东西,开发者想要显示底层的演示效果,就需要使用API来完成,如果想要不同的演示效果,又需要考虑选择哪个版本的API,也就是文章的标题提到的:如何选择targetSdkVersion属性值的问题。

二、如何选择targetSdkVersion

一个Android系统,对外提供一套API,如何选择targetSdkVersion取决于应用程序需要实现的功能,如果你的应用程序使用API 7就可以实现的功能,可以不用考虑使用API 24,使用低版本API的其中一个好处,可以让更多的Android系统运行的效果保持一致,即兼容性更好,打个比方:API 7开发的APP可能兼容98%以上的Android手机,而API 24开发的APP可能兼容仅有60%,所谓的不兼容并不是无法正常运行,而是在不同Android系统的手机运行的效果差异比较大,会让用户感觉难以接受;使用低版本API的其中一个不足,显示的效果比较OUT,提供的可用的接口或类比较少,本来一句代码可以完成的功能(封装的类或接口),需要自己花一天琢磨写很多的代码,也就是有高版本API的其中一个原因,提供更多的或封装好的应用程序接口让开发者使用。

手机的版本>targetSdkVersion

项目运行效果为targetSdkVersion 版本。譬如项目targetSdkVersion是22,那么项目里没做6.0(23)权限处理,调用危险权限如相机不会出现闪退和提示,照常运行,项目特性运行到22版本。

手机的版本=targetSdkVersion

如果目标设备的API版本正好等于此数值, 他会告诉Android平台:此程序在此版本已经经过充分测,没有问题。不必为此程序开启兼容性检查判断的工作了。 也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。 但是,这个设置仅仅是一个声明、一个通知,不会有太实质的作用

同时,高版本API会针对低版本存在的问题进行改进和完善,摈弃一下不用的类或接口,新增一些方法或属性,如果你使用的方法是在某个API被另一个方法代替的话,你可能就得在代码中区分APP是运行在哪个版本的Android系统,一个很典型的例子:WebChromeClientonShowFileChooser()方法和openFileChooser()方法,如果你的targetSdkVersion小于19,在处理WebView上传表单的数据的时候就需要重写openFileChooser方法;如果你的targetSdkVersion大于或等于19,你就必须同时重写onShowFileChooseropenFileChooser两个方法,openFileChooser方法在Android 4.0以下系统被回调,另一则在Android 4.0以上系统被回调。这是高低版本API摈弃或新增一些类和方法时需要注意的其中一个问题。

API版本号和Android系统关系

了解并学习Android 4.x、Android 5.x、Android 6.x或Android 7.x系统的特性,重点掌握不同系统同一个功能的实现方式,即行为变更,特点:变更的行为在当前系统或更高系统版本中被支持,一个简单的例子:Android 7.0系统其中的一个行为变更是权限更改,尝试传递file:// URI 的方式写入本地文件或读取本地文件,使用API 24开发的APP将会触发 FileUriExposedException异常,请求拍照并保存到本地的正确的写法,如下:


    /**
     * 调用系统相机
     */
    private void goToTakePhoto() {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            File file = new File(mSDCardPath, System.currentTimeMillis() + ".jpg");
            /**Android 7.0以上的方式**/
            Uri contentUri = getUriForFile(this, getString(R.string.install_apk_path), file);
            grantUriPermission(getPackageName(), contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
            /**Android 7.0以前的方式**/
//            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
            startActivityForResult(intent, RESULT_CAPTURE_IMAGE);
        } else {
            Toast.makeText(this, "sdcard不存在", Toast.LENGTH_SHORT).show();
        }
    }

想要查看完整的例子,文章后面附上源码,可以下载测试。本来已经代码可以实现的拍照功能,API 24开发的APP在Android 7.0以上系统需要至少四个步骤:

  1. 在AndroidManifest.xml文件中定义一个FileProvider
  2. 指定写入或读取本地文件的目录
  3. 生成完整的URI
  4. 请求授予URI权限
  5. 实现手机拍照并保存本地功能

三、关于minSdkVersion和compileSdkVersion

注意,如果使用 Support Library ,那么使用最新发布的 Support Library 就需要使用最新的 SDK 编译。例如,要使用 23.1.1 版本的 Support Library ,compileSdkVersion 就必需至少是 23 (大版本号要一致!)。通常,新版的 Support Library 随着新的系统版本而发布,它为系统新增加的 API 和新特性提供兼容性支持

minSdkVersion定义应用程序支持的最低API版本,最低版本设置为API 11,目标版本设置为API 24,那么应用程序调用使用API 14提供的方法时,Android Studio或Eclipse开发工具将提醒开发者引用一个未定义的方法,使用该方法需要将minSdkVersion设置为API 14以上,如下图:

minSdkVersion含义

继续在上述代码,造成的结果大于或等于Android 4.0的系统可以正常执行,小于Android 4.0的系统将在运行时尝试访问不可用的 API 时发生崩溃。

compileSdkVersion定义应用程序编译选择哪个Android SDK版本,通常compileSDKVersion属性值被设置为最新的API版本,例如:25,改变compileSDKVersion的属性值不会影响Android系统运行行为,比如说,将属性值设置为25,targetSdkVersion属性值为23,代码如下:

    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "cn.teachcourse.demos"
        minSdkVersion 11
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

开发的应用程序在Android 7.0系统运行,不会以Android 7.0新增的行为运行,决定Android系统行为的仍然是targetSDKVersion,那么compileSDKVersion有什么用呢?选择最新的API版本,在编译的时候检查代码的错误和警告,提示开发者修改和优化,因为通常在Android项目中会引入第三方的支持库,支持库使用了23.1.1版本,compileSdkVersion的属性值至少为23.0.0,新版本的支持库的发布紧跟着对应的Android系统平台,能够更好的兼容。

四、targetSdkVersion、minSdkVersion和CompileSdkVersion之间的关系

记住一点:Android系统平台的行为变更,只有targetSdkVersion的属性值被设置为大于或等于该系统平台的API版本时,才会生效;compileSdkVersion属于Android编译项目时其中的一项配置,主要区别是compileSDKVersion在不会被打包的APK文件中,targetSdkVersionminSdkVersion将被打包到APK文件中,具体可以解压APK文件后,查看AndroidManifest.xml文件,如下图:

targetSdkVersion区别

你会发现在使用Android Studio开发工具时,手动修改AndroidManifest.xml的属性值,使用Gradle构建后,将会被忽略,最终生成的是build.gradle配置文件指定的属性值。它们之间的关系如下:

minSdkVersion <= targetSdkVersion <= compileSdkVersion

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值