Android Min SDK版本与目标SDK版本

当谈到开发Android应用程序时,Min和Target SDK版本有什么区别? Eclipse不会让我创build一个新的项目,除非Min和Target版本是相同的!

安卓的minSdkVersion

指定应用程序运行所需的最低API级别的整数。 如果系统的API级别低于此属性中指定的值,Android系统将阻止用户安装应用程序。 你应该总是声明这个属性。

机器人:targetSdkVersion

指定应用程序目标的API级别的整数。

有了这个属性集,应用程序说它能够运行在较老的版本上(下到minSdkVersion),但是被明确地testing过,可以在这里指定版本。 指定此目标版本允许平台禁用目标版本不需要的兼容性设置(否则可能会打开以保持向前兼容性),或启用较旧应用程序无法使用的较新function。 这并不意味着您可以针对不同版本的平台编写不同的function – 它只是通知平台您已经针对目标版本进行了testing,平台不应该执行任何额外的工作来维持与目标版本的向前兼容性。

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

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

OP对这个问题发表的评论(基本上说,targetSDK不影响应用程序的编译)是完全错误的! 对不起,生硬。

简而言之,这里是从minSDK中声明一个不同的targetSDK的目的:这意味着你正在使用来自更高级别的SDK的function,而不是最小的,但是你已经确保向后兼容 。 换句话说,假设您想要使用最近才引入的function,但这对您的应用程序并不重要。 然后,您可以将targetSDK设置为引入此新function的版本,将最小值设置为更低,以便每个人都可以使用您的应用程序。

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

再举一个例子,如果你想使用Gingerbread或者Honeycomb的特性,你可以使用它。 有些人很快就会得到更新,但是其他许多人,尤其是老硬件,可能会一直停留在Eclair,直到他们购买新设备。 这可以让你使用一些很酷的新function,但是不会排除你的可能市场的一部分。

Android开发者的博客中有一篇关于如何使用这个特性的非常好的文章,特别是如何devise上面提到的“使用它之前检查特性是否存在”的代码。

对于OP:我写这主要是为了将来偶然遇到这个问题的任何人的利益,因为我知道你很久以前问过你的问题了。

当您设置targetSdkVersion =“xx”时,您certificate您的应用程序在API级别xx正常工作(例如,已经被彻底和成功testing)。

在xx 以上的API级别运行的Android版本将自动应用兼容性代码,以支持您可能依赖的API级别xx之前或之前提供的任何function,但现在在Android版本的更高级别上已经过时。

相反,如果您正在使用 xx级别之前之前已经过时的任何function,那么兼容性代码将不会被更高API级别(不再包括这些function)的操作系统版本自动应用以支持这些用途。 在这种情况下,你自己的代码必须有testingAPI级别的特殊情况条款,如果检测到的操作系统级别较高,不再具有给定的APIfunction,则代码必须使用在运行的操作系统上可用的备用functionAPI级别。

如果它不能做到这一点,那么一些界面function可能根本不会出现,通常会触发代码中的事件,而且您可能会缺less用户需要触发这些事件并访问其function的关键界面function(如下面的例子)。

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

为了警告开发人员专门testing使用某项function所需的最低API级别,如果代码包含对在稍后的API级别定义的任何方法的调用,则编译器将发出错误(不仅仅是警告),而是比minSdkVersion,即使targetSdkVersion大于或等于该方法第一次可用的API级别。 要删除这个错误,编译器指令

@TargetApi(nn) 

告诉编译器,在调用任何依赖于至less具有该API级别的方法之前,已经编写了该指令(其将在方法或类之前)的范围内的代码以testing至lessnn的API级别。 例如,下面的代码定义了一个方法,可以从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(); } } 

如果您已经在更高级别进行了testing并且所有工作都正常,即使您没有使用比minSdkVersion更高的API级别的任何function, 可能需要声明更高的targetSdkVersion。 这只是为了避免访问兼容性代码的开销,以适应从目标级别到最低级别,因为您已经确认(通过testing)不需要这样的适配。

取决于声明的targetSdkVersion的UIfunction的一个示例将是当targetSdkVersion小于11的应用程序的状态栏上出现的三个垂直点菜单button,当这些应用程序在API 11及更高版本上运行时。 如果您的应用程序的targetSdkVersion为10或更低,则假定您的应用程序的界面取决于是否存在专用菜单button,因此三点button似乎取代了以前的专用硬件和/或屏幕版本当操作系统具有更高的API级别时,该button(例如,如在姜饼中所看到的)不再采用设备上的专用菜单button。 但是,如果将应用程序的targetSdkVersion设置为11或更高,则假定您已经利用了在该级别引入的用于replace专用菜单button(例如,Action Bar)的function,或者您已经规避了需要有一个系统菜单button; 因此,三点垂直点菜单“兼容性button”消失。 在这种情况下,如果用户找不到菜单button,她就不能按下它,而这又意味着你的活动的onCreateOptionsMenu(菜单)覆盖可能永远不会被调用,这又意味着您的应用程序function的重要组成部分可能会被剥夺其用户界面。 当然,除非您已经实施了操作栏或用于访问这些function的其他一些手段。

相反,minSdkVersion声明设备的操作系统版本至less具有该API级别才能运行您的应用程序。 这会影响哪些设备可以在Google Playapp store(以及其他可能的app store)上看到并下载您的应用。 这是一种说明您的应用程序依赖于在该级别build立的操作系统(API或其他)function的方式,并且没有可接受的方式来处理这些function的缺失。

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

一个概念总是可以通过例子更好地传达 。 我在理解这些概念时遇到了困难,直到我深入Android框架源代码,并做了一些实验,甚至在阅读Android开发人员站点和相关的stackoverflow线程中的所有文档之后。 我会分享两个例子,帮助我完全理解这些概念。

DatePickerDialog将根据您在AndroidManifest.xml文件的targetSDKversion( <uses-sdk android:targetSdkVersion="INTEGER_VALUE"/> )中放置的级别显示不同。 如果将值设置为10或更低,则DatePickerDialog将如左图所示。 另一方面,如果将值设置为11或更高,则DatePickerDialog将看起来像是正确的, 代码非常相似

使用targetSDKversion 10或更低版本查看DatePickerDialog使用targetSDKversion 11或更高版本查看DatePickerDialog

我用来创build这个示例的代码是非常简单的。 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> 

而已。 这是我需要testing的每一个代码。

当你看到Android框架的源代码时,这种外观的变化是清晰的。 它如下所示:

 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框架中的这里和那里find。

另一个例子是关于WebView类。 应该在主线程上调用Webview类的公共方法,如果不是,则当您将targetSDKversion设置为18或更高时,运行时系统将引发RuntimeException 。 这种行为可以通过源代码清楚地传递出来。 这只是写这样的。

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

Android的文档说:“ 随着Android每个新版本的发展,一些行为,甚至外观可能会改变 。 所以,我们看到了行为和外观的变化,以及这种变化是如何实现的。

总之,Android文档中提到“ 此属性(targetSdkVersion)通知系统您已经针对目标版本进行了testing,并且系统不应该启用任何兼容性行为来维持您的应用程序与目标版本的向前兼容性 ”。 在WebView的情况下,这真的很清楚。 直到JELLY_BEAN_MR2发布,才能在非主线程上调用WebView类的公共方法。 如果Android框架在JELLY_BEAN_MR2设备上抛出一个RuntimeException,这是无稽之谈。 它不应该为了自己的利益而使新引入的行为成为致命的结果。 所以,我们要做的是检查某些targetSDKversions上的一切是否正常。 通过设定更高的目标SDK版本,我们得到像增强外观一样的好处,但它带有责任。

编辑:免责声明。 DatePickerDialog构造函数根据当前的targetSDKversion(上面显示的)设置不同的主题,在以后的提交中实际上已经改变了。 不过,我用这个例子,因为逻辑没有改变,这些代码片段清楚地显示了targetSDKversion的概念。

对于那些想要总结的人来说,

 android:minSdkVersion 

是您的应用程序支持的最低版本。 如果您的设备的Android版本较低,应用程序将不会安装。

而,

 android:targetSdkVersion 

是应用程序devise运行的API级别。 意思是说,你的手机系统不需要使用任何兼容性保证,因为你已经testing了这个API。 此外,这允许您使用这个目标版本的一些function,但不是所有的function。

赠品 –

android:maxSdkVersion

如果你的设备的API版本更高,应用程序将不会安装。 IE浏览器。 这是最大的API,直到你允许你的应用程序安装。

即。 对于MinSDK -4,maxSDK – 8,targetSDK – 8我的应用程序将工作在最低1.6,但我也使用了仅在2.2中支持的function,如果它安装在2.2设备上将是可见的。 另外,对于maxSDK – 8,这个应用程序不会安装在使用API​​> 8的手机上。

较小的参考

解释参考

如果你得到一些编译错误,例如:

 <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或更高,它将运行没有问题。 所以你必须确定你在一个由版本检查保护的执行path上调用这个方法。 TargetApi只是允许你编译它,但你自己承担风险。

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

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

android:targetSdkVersion:目标sdk版本是设置应用的目标API级别。 如果这个属性没有在清单中声明,minSdk版本将是你的TargetSdk版本。 这总是对“我们宣布为TargetSdk版本的所有更高版本的API上的应用程序支持安装”。 为了使应用程序有限的目标,我们需要在我们的清单文件中声明maxSdkVersion …

如果您正在制作需要危险权限的应用程序, 并将targetSDK设置为23或更高 ,则应该小心。 如果你没有在运行时检查权限,你将会得到一个SecurityException,如果你在一个try块中使用了代码,例如open camera,如果你没有检查logcat,很难检测到错误。