首页 文章

Android Min SDK版本与目标SDK版本

提问于
浏览
426

在开发Android应用程序时,Min和Target SDK版本有什么区别?除非Min和Target版本相同,否则Eclipse不会让我创建一个新项目!

9 回答

  • 1

    android:minSdkVersion

    一个整数,指定应用程序运行所需的最低API级别 . 如果系统的API级别低于此属性中指定的值,则Android系统将阻止用户安装应用程序 . 您应该始终声明此属性 .

    android:targetSdkVersion

    一个整数,指定应用程序所针对的API级别 .

    使用此属性集,应用程序表示它能够在较旧版本(低至minSdkVersion)上运行,但已明确测试以使用此处指定的版本 . 指定此目标版本允许平台禁用目标版本不需要的兼容性设置(否则可以打开以保持向前兼容性)或启用旧应用程序不可用的较新功能 . 这并不意味着您可以为不同版本的平台编写不同的功能 - 它只是通知平台您已针对目标版本进行了测试,并且平台不应执行任何额外的工作来保持与目标版本的向前兼容性 .

    有关更多信息,请参阅以下URL:

    http://developer.android.com/guide/topics/manifest/uses-sdk-element.html

  • 50

    OP发布的问题评论(基本上说明targetSDK不会影响应用程序的编译)是完全错误的!对不起,直截了当 .

    简而言之,这里的目的是从minSDK声明一个不同的targetSDK:这意味着你使用的是比你的最低级别更高级别的SDK的功能,但你有 ensured backwards compatibility . 换句话说,假设您想要使用最近才引入的功能,但这对您的应用程序并不重要 . 然后,您可以将targetSDK设置为引入此新功能的版本,并将最小值设置为较低的值,以便每个人仍然可以使用您的应用 .

    举个例子,假设你正在编写一个广泛使用手势检测的应用程序 . 但是,手势可以识别的每个命令也可以通过按钮或菜单完成 . 在这种情况下,手势是“额外的酷”,但不是必需的 . 因此,您可以将目标sdk设置为7(当引入GestureDetection库时为“Eclair”),将最低SDK设置为3级(“Cupcake”),这样即使拥有真正旧手机的人也可以使用您的应用程序 . 您所要做的就是确保您的应用在尝试使用手势库之前检查了其运行的Android版本,以避免在不存在时尝试使用它 . (不可否认,这是一个过时的例子,因为几乎没有人还有v1.5手机,但有一段时间保持与v1.5的兼容性非常重要 . )

    再举一个例子,如果你想使用Gingerbread或Honeycomb的功能,可以使用它 . 有些人很快就会得到更新,但许多其他人,特别是使用较旧的硬件,可能会一直困在Eclair,直到他们购买新设备 . 这将让您使用一些很酷的新功能,但不排除部分可能的市场 .

    Android developer's blog中有一篇关于如何使用此功能的非常好的文章,特别是如何设计我上面提到的"check the feature exists before using it"代码 .

    对于OP:我写这篇文章主要是为了将来碰巧遇到这个问题的任何人的利益,因为我意识到很久以前你的问题就被提出了 .

  • 1

    当您设置targetSdkVersion =“xx”时,您证明您的应用在API级xx上正常运行(例如,已经过彻底和成功测试) .

    在xx以上的API级别运行的Android版本将自动应用兼容性代码,以支持API级别xx之前或之前可能依赖的任何功能,但现在已在Android版本的更高级别上淘汰 .

    相反,如果您使用的是在xx级别之前或之前已过时的任何功能,则兼容性代码将不会由更高API级别的操作系统版本(不再包括这些功能)自动应用以支持这些用途 . 在这种情况下,您自己的代码必须具有测试API级别的特殊情况子句,并且如果检测到的操作系统级别更高,不再具有给定的API功能,则您的代码必须使用正在运行的操作系统中可用的备用功能 . API级别 .

    如果它无法执行此操作,则可能根本不会出现通常会触发代码中的事件的某些界面功能,并且您可能缺少用户触发这些事件并访问其功能所需的关键界面功能(如例子如下) .

    如其他答案中所述,如果您想最初使用某些API功能,可以将targetSdkVersion设置为高于minSdkVersion在比您的minSdkVersion更高的API级别定义,并已采取措施确保您的代码能够检测并处理缺少比targetSdkVersion更低级别的那些功能 .

    为了警告开发人员专门测试使用功能所需的最低API级别,如果代码包含对在minSdkVersion之后的API级别定义的任何方法的调用,编译器将发出错误(而不仅仅是警告),即使targetSdkVersion大于或等于该方法首次可用的API级别 . 要删除此错误,请使用编译器指令

    @TargetApi(nn)
    

    告诉编译器在调用依赖于至少具有该API级别的任何方法之前,已编写该指令范围内的代码(将在方法或类之前)以测试至少nn的API级别 . 例如,以下代码定义了一个方法,该方法可以从app中的代码调用,该代码的minSdkVersion小于11且targetSdkVersion为11或更高:

    @TargetApi(11)
        public void refreshActionBarIfApi11OrHigher() {
          //If the API is 11 or higher, set up the actionBar and display it
          if(Build.VERSION.SDK_INT >= 11) {
            //ActionBar only exists at API level 11 or higher
            ActionBar actionBar = getActionBar();
    
            //This should cause onPrepareOptionsMenu() to be called.
            // In versions of the API prior to 11, this only occurred when the user pressed 
            // the dedicated menu button, but at level 11 and above, the action bar is 
            // typically displayed continuously and so you will need to call this
            // each time the options on your menu change.
            invalidateOptionsMenu();
    
            //Show the bar
            actionBar.show();
        }
    }
    

    如果您已经在更高级别进行了测试并且一切正常,您可能还需要声明更高的targetSdkVersion,即使您没有使用API级别高于minSdkVersion的任何功能 . 这只是为了避免访问旨在从目标级别调整到最低级别的兼容性代码的开销,因为您已经确认(通过测试)不需要这样的调整 .

    取决于声明的targetSdkVersion的UI功能的示例将是当这些应用在API 11及更高版本下运行时,具有小于11的targetSdkVersion的应用的状态栏上出现的三垂直点菜单按钮 . 如果您的应用的targetSdkVersion为10或更低,则假定您的应用的界面取决于是否存在专用菜单按钮,因此三点式按钮似乎取代了早期的专用硬件和/或屏幕版本当OS具有较高的API级别时,该按钮(例如,如Gingerbread中所见),不再假设设备上的专用菜单按钮 . 但是,如果您将应用程序的targetSdkVersion设置为11或更高,则假定您已利用该级别引入的功能替换专用菜单按钮(例如,操作栏),或者您已经规避了需要有一个系统菜单按钮;因此,三垂直点菜单“兼容性按钮”消失 . 在这种情况下,如果用户找不到菜单按钮,则她无法按下它,反过来,这意味着您的活动的onCreateOptionsMenu(菜单)覆盖可能永远不会被调用,这反过来又意味着应用程序功能的重要部分可能会被剥夺其用户界面 . 当然,除非您已经实施了操作栏或其他一些替代方法供用户访问这些功能 .

    相比之下,minSdkVersion声明要求设备的操作系统版本至少具有该API级别才能运行您的应用程序 . 这会影响哪些设备可以在Google Play应用商店(以及其他可能的应用商店)上查看和下载您的应用 . 这是一种说明您的应用程序依赖于在该级别上 Build 的OS(API或其他)功能的方式,并且没有可接受的方式来处理这些功能的缺失 .

    使用minSdkVersion确保存在与API无关的功能的一个示例是将minSdkVersion设置为8,以确保您的应用程序仅在启用JIT的Dalvik解释器版本上运行(自JIT引入以来)到API级别的Android解释器8) . 由于启用JIT的解释器的性能可能是缺少该功能的解释器的五倍,因此如果您的应用程序大量使用处理器,那么您可能需要API级别8或更高级别以确保足够的性能 .

  • 860

    A concept can be better delivered with examples, always . 直到我深入研究Android框架源代码并进行一些实验,即使在阅读了Android开发者网站和相关stackoverflow线程中的所有文档之后,我也无法理解这些概念 . 我将分享两个帮助我完全理解这些概念的例子 .

    根据您放入AndroidManifest.xml文件的targetSDKversion( <uses-sdk android:targetSdkVersion="INTEGER_VALUE"/> )中的级别,DatePickerDialog看起来会有所不同 . 如果将值设置为10或更低,则DatePickerDialog将如左图所示 . 另一方面,如果将值设置为11或更高,则DatePickerDialog将如右图所示, with the very same code .

    DatePickerDialog look with targetSDKversion 10 or lower

    DatePickerDialog look with targetSDKversion 11 or higher

    我用来创建这个示例的代码非常简单 . MainActivity.java 看起来:

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void onClickButton(View v) {
            DatePickerDialog d = new DatePickerDialog(this, null, 2014, 5, 4);
            d.show();       
        }
    }
    

    activity_main.xml 看起来:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickButton"
        android:text="Button" />
    </RelativeLayout>
    

    那个's it. That'确实是我需要测试的所有代码 .

    当你看到Android framework source code时,这种外观的变化就很明显了 . 它像:

    public DatePickerDialog(Context context,
        OnDateSetListener callBack,
        int year,
        int monthOfYear,
        int dayOfMonth,
        boolean yearOptional) {
            this(context, context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB
                    ? com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert
                    : com.android.internal.R.style.Theme_Dialog_Alert,
            callBack, year, monthOfYear, dayOfMonth, yearOptional);
    }
    

    如您所见,框架获取当前的targetSDKversion并设置不同的主题 . 这种代码片段( getApplicationInfo().targetSdkVersion >= SOME_VERSION )可以在Android框架中找到 .

    另一个例子是关于WebView类 . Webview类的公共方法应该在主线程上调用,如果没有,运行时系统会在设置targetSDKversion 18或更高版本时抛出 RuntimeException . 使用its source code可以清楚地传达此行为 . 它就是这样写的 .

    sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
                Build.VERSION_CODES.JELLY_BEAN_MR2;
    
    if (sEnforceThreadChecking) {
        throw new RuntimeException(throwable);
    }
    

    The Android doc说,“随着Android每个新版本的发展,一些行为甚至出现都可能会改变 . ”因此,我们看到了行为和外观的变化,以及如何实现这种变化 .

    总之,Android文档说“此属性(targetSdkVersion)通知系统您已针对目标版本进行了测试,并且 the system should not enable any compatibility behaviors 维护您的应用程序与目标版本的向前兼容性 . ” WebView案例非常清楚 . 直到JELLY_BEAN_MR2发布才能在非主线程上调用WebView类的公共方法 . 如果Android框架在JELLY_BEAN_MR2设备上抛出RuntimeException,这是无稽之谈 . 它不应该为其兴趣启用新引入的行为,这会导致致命的结果 . 因此,我们要做的是检查某些targetSDKversions上是否一切正常 . 我们通过设置更高的targetSDKversion获得外观增强等好处,但它带来了责任 .

    编辑:免责声明 . 基于当前targetSDKversion(我在上面显示的)设置不同主题的DatePickerDialog构造函数实际上已在later commit中更改 . 然而我使用了这个例子,因为逻辑没有被改变,那些代码片段清楚地显示了targetSDKversion概念 .

  • 9

    对于那些想要总结的人,

    android:minSdkVersion
    

    是您的应用程序支持的最低版本 . 如果您的设备有较低版本的Android,应用程序将无法安装 .

    而,

    android:targetSdkVersion
    

    是您的应用程序设计运行的API级别 . 意味着,您的手机系统不需要使用任何兼容性行为来保持向前兼容性,因为您已经过测试直到此API .

    Your app will still run on Android versions higher than given targetSdkVersion but android compatibility behaviour will kick in.

    Freebie -

    android:maxSdkVersion

    如果您的设备的API版本较高,则不会安装应用 . IE浏览器 . 这是您允许应用安装的最高API .

    即 . 对于MinSDK -4,maxSDK - 8,targetSDK - 8我的应用程序将在最小1.6上运行,但我也使用仅在2.2中支持的功能,如果它安装在2.2设备上将可见 . 此外,对于maxSDK - 8,此应用程序不会安装在使用API> 8的手机上 .

    在撰写此答案时,Android文档在解释它时没有做得很好 . 现在它得到了很好的解释 . Check it here

  • 0

    如果您遇到一些编译错误,例如:

    <uses-sdk
                android:minSdkVersion="10"
                android:targetSdkVersion="15" />
    

    .

    private void methodThatRequiresAPI11() {
            BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inPreferredConfig = Config.ARGB_8888;  // API Level 1          
                    options.inSampleSize = 8;    // API Level 1
                    options.inBitmap = bitmap;   // **API Level 11**
            //...
        }
    

    你得到编译错误:

    字段需要API级别11(当前最小值为10):android.graphics.BitmapFactory $ Options#inBitmap

    从Android开发工具(ADT)的第17版开始,有一个新的非常有用的注释 @TargetApi 可以很容易地解决这个问题 . 在包含有问题的声明的方法之前添加它:

    @TargetApi
    private void methodThatRequiresAPI11() {            
      BitmapFactory.Options options = new BitmapFactory.Options();
          options.inPreferredConfig = Config.ARGB_8888;  // API Level 1          
          options.inSampleSize = 8;    // API Level 1
    
          // This will avoid exception NoSuchFieldError (or NoSuchMethodError) at runtime. 
          if (Integer.valueOf(android.os.Build.VERSION.SDK) >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            options.inBitmap = bitmap;   // **API Level 11**
                //...
          }
        }
    

    现在没有编译错误,它将运行!

    编辑:这将导致API级别低于11的运行时错误 . 在11或更高版本上它将运行没有问题 . 因此,您必须确保在由版本检查保护的执行路径上调用此方法 . TargetApi只允许您编译它,但您自己承担风险 .

  • 21

    android:minSdkVersionandroid:targetSdkVersion 都是我们需要在android清单文件中声明的Integer值,但两者都具有不同的属性 .

    android:minSdkVersion: 这是运行Android应用程序所需的最低API级别 . 如果我们将在较低的API版本上安装相同的应用程序,则会出现解析器错误,并且将出现应用程序不支持问题 .

    android:targetSdkVersion: 目标sdk版本是设置应用程序的目标API级别 . 如果未在清单中声明此属性,则minSdk版本将是您的TargetSdk版本 . 这总是如此"app support installation on all higher version of API we declared as TargetSdk Version" . 要使app限制目标,我们需要在清单文件中声明maxSdkVersion ...

  • 134

    Target sdk是您要定位的版本,min sdk是最小的版本 .

  • 95

    如果您正在制作应用程序 require dangerous permissions and set targetSDK to 23 or above ,您应该小心 . 如果你没有检查运行时的权限,你将得到一个SecurityException,如果你在try块中使用代码,例如打开相机,如果不检查logcat,则很难检测到错误 .

相关问题