android - 安卓Min SDK Version vs. Target SDK Version

  显示原文与译文双语对照的内容

在为Android开发应用程序时,最小和目标SDK版本有什么不同? Eclipse 不会让我创建一个新项目,除非最小和目标版本相同 !

时间:

android:minSdkVersion

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

android:targetSdkVersion

一个整数,表示应用程序正在启动的API级别。

通过这个属性集,应用程序说它可以在旧版本的( 向下到 minSdkVersion ) 上运行,但是被显式测试为使用这里指定的版本。 指定这里目标版本允许平台禁用目标版本( 为了维护 forward-compatibility,它可能会被打开) 不需要的兼容性设置,或者启用较旧的应用程序不可用的新功能。 这并不意味着你可以为不同版本的platform—it编写不同的功能,只是通知平台你已经针对目标版本进行了测试,平台不应该执行任何额外的工作来维护与目标版本的forward-compatibility 。

有关详细信息,请参阅这里 URL:

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

由下面的操作发表的评论( 基本上说targetSDK不影响应用程序的编译) 完全错误 ! 抱歉,be了。

简而言之,这里的目的是声明一个不同的targetSDK: 则表明你正在使用的功能从高能级SDK比你的下限,但你拥有 保证了向后兼容 。 换句话说,假设你想使用最近引入的特性,但这对你的应用程序来说并不重要。 然后,你将把targetSDK设置为引入这个新特性的版本,并将最小值设置为低一些,这样每个人仍然可以使用你的应用程序。

举一个例子,假设你正在编写一个应用了手势检测的应用。 但是,手势可以识别的每个命令也可以通过按钮或者菜单来完成。 在这种情况下,手势是一个'冷却额外的',但不是必需的。 非常旧的手机则可以用你app,因此便可以设置目标sdk为 7 ("eclair"GestureDetection库被引入时),而对水平 3 minimumSDK ("杯子蛋糕"),这样一来,people. 你所要做的就是确保你的应用在尝试使用手势库之前检查它运行的Android版本,以避免试图使用它。 ( 这是个过时的例子,因为几乎没有人还拥有v1.5电话,但是有一个时间与v1.5保持兼容性真的很重要。)

如果你想使用姜饼或者 Honeycomb的特性,你可以使用另一个例子。 一些人很快就会得到更新,但是很多人,尤其是老的硬件,在购买新设备之前,可能会一直坚持使用 Eclair 。 这将让你使用一些很酷的新特性,但不排除你可能的市场部分。

有关如何使用这里功能有一个真正的好文章从开发人员 机器人博客,和我上面提到的"在使用该功能之前先检查它是否存在"特别是,如何设计代码。

到 OP: 我写了这主要用于任何人的好处在于碰巧偶然发现这个问题以后,因为我意识到,你的问题是很久以前问。

设置 targetsdkversion="xx"时,验证你的应用程序在API级别的( e.g,已经被彻底且成功地测试过) 上工作正常。

安卓一个API层上运行的一个版本上面 xx将应用兼容性,你可能会依赖于你那就是可用的代码会自动以支持任何功能或者API级别的早期 xx,但它已经过时,在那个安卓版本的级别越高。

相反地,如果你正在使用的任何功能都变得已经过时在 或者 到级别的早期认识,这由操作系统版本不兼容的代码将 被自动应用在更高的API级别( 不再包括那些特性) 来支持不同的用途。 可以用在运行很多操作系统level,在那种情况下,你自己的代码必须有子句,测试该API级别和操作系统级别的,如果检测到了更高的一个特例,它不再有给定的API功能,你的代码必须使用其他功能,应 available.

如果它无法做到这一点,那么或许就不会出现一些接口功能正常触发事件在你的代码,并且你可能缺少一个重要接口的功能,而且用户必须来触发那些事件和( 如下面的示例所示) 才能访问它的功能。

按照规定在其他答案,你可能设置targetSdkVersion超过minSdkVersion如果你想要使用一些API功能最初定义在更高的API级别比你 minSdkVersion,并已经采取了一些措施以确保你的代码可以检测和处理由于没有这些功能比targetSdkVersion较低级别。

为了提醒开发人员要确实所需的最小API级别的测试使用功能,编译器将发出一个错误( 不只是一个警告) 比 minSdkVersion,如果代码中包含一个调用任何方法,它是在稍后的API级别定义,即使targetSdkVersion是大于或者等于该 API,方法第一次制作可以哪个层次上。 若要删除这里错误,编译器指令

 
@TargetApi(nn)

 

命名空间范围内的指令( 它将先于方法或者类) 会告知编译器该代码已经写入测试原料药级别最低为nn的方法之前,任何方法,它取决于该原料药具有至少水平。 例如下面的代码定义了一个方法,该方法可以从代码中调用一个应用程序,它有一个小于 11和一个 11或者更高的targetSdkVersion: minSdkVersion 。


@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 上面, 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();
 }
}

在一个API级别高于你的你可能还 想声明一个更高targetSdkVersion如果你有测试过在那个更高级的和一切都工作正常,即使你当时不用任何特徵。 这将是仅为了避免访问的开销兼容性代码意在适应从目标层面到最小水平,因为你必须确认( 通过测试) 那不这个适应是必需的。

一个示例用户界面功能,取决于所声明targetSdkVersion将会被了three-vertical-dot菜单按钮,出现在状态栏上的应用程序具有一个targetSdkVersion小于 11,当这些应用均运行在 API 11.高。 在设备上已经不再assumed,如果你的应用程序也有 targetSdkVersion 10或者下方,这里假定你的操作界面的应用取决于是否存在一个专门的菜单按钮,并且因此three-dot按钮似乎取代了较早的专用硬件和/或者屏幕上的版本的那个按钮( e.g,就像姜饼中看到的) 可以在操作系统都具有较高的API级别为它的一个专门的菜单按钮。 但是,如果你设置你的应用程序以 11 targetSdkVersion或者更高版本中,假定你能够加以利用的新增功能以替代专用的菜单按钮( e.g,操作栏)的,或者你是否有该级别的否则回避了需要有一个系统菜单按钮;因此,该"兼容性按钮"three-vertical-dot菜单消失。 在这种情况下,如果用户找不到一个菜单按钮,她按不到它,而且反过来,就意味着你的Activity onCreateOptionsMenu(menu) 再次重写,它可能永远不会被调用,同样意味着,一个重要的你可能是丧失了,此时系统功能,它的用户界面的一部分。 于用户要访问这些 features,,除非,当然,你已经实施相关的动作栏或者其他一些替代方法排除这些余热

为了运行你的app, minSdkVersion该原料药,相比之下,指明的是需要对它操作系统的设备版本至少有水平线。 当你的应用程序在 Google Play App Store ( 还有其他应用商店,也可能) 上时,它会影响哪些设备可以查看并下载你的应用程序。 但是由于没有这些features,据的一种方式,表明你的应用也依靠操作系统( API或者其他) 功能,均在该级别,因此没有与建立可以接受的方式来 deal.

在一个JIT-enabled版本的Dalvik解释器使用minSdkVersion来确保的一个例子的存在特征么不 API-related将是要设置minSdkVersion到 8为了保证你的应用将运行得盘算。 而为了保证足够的performance,因为一个JIT-enabled解释器可以多达五次的性能会的一个缺少该功能,如果你的应用程序将大量使用了处理器然后你可能希望要求API级别 8或者 上面.

对于那些想要总结的人


android:minSdkVersion

在你的应用程序支持之前,最低版本。 如果你的设备版本较低,应用程序将不会安装。


android:targetSdkVersion

你的应用程序设计为运行的API级别。 意味着,你的电话系统不需要使用任何兼容beahviors来维持向前兼容性,因为你已经对这个API进行了测试。 同样,这允许你使用英镑,但不是来自这里目标版本的所有功能。

免费-

android:maxSdkVersion

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

IE 。对于 MinSDK -4,maxSDK - 8,targetSDK - 8的应用将在最小 1.6上工作,但我也使用了仅支持 2.2的功能,如果它安装在一个 2.2设备上。 同样,对于 maxSDK - 8,这个应用不会在使用 API> 8的手机上安装。

较小引用

解释了引用

结合例子,总是, 一个概念可以更好的delivered. 我有麻烦,在理解这些概念,直到我钻研安卓框架的源代码,并做了相关实验,即使在阅读中所有文档安卓开发者网站 & stackoverflow线程。 我将分享两个示例,帮助我充分理解这些概念。

DatePickerDialog 将根据你放置在文件 AndroidManifest.xml targetSDKversion中的级别看起来不同 <uses-sdk android:targetSdkVersion="INTEGER_VALUE"/> ) 如果你设置值 10或者更低,你的DatePickerDialog看起来就像左边一样。 这样相同代码, 在 DatePickerDialog 11或者更高,另一方面,如果你设置的值将类似于右, .

DatePickerDialog look with targetSDKversion 10 or lowerDatePickerDialog look with targetSDKversion 11 or higher

我用来创建这个样例的代码是 super-simple 。 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>


就是这样,这就是我需要测试的每一个代码。

当你看到 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并设置不同的主题。 这种代码 Fragment ( getApplicationInfo().targetSdkVersion> = SOME_VERSION 在Android框架中可以找到) 。

另一个示例是关于 web view web 类。 公用的类方法应该是主线程上调用,和 web view如果没有,运行时系统将引发 RuntimeException,当你设置 targetSDKversion 18或者更高。 这里行为可以通过的源代码显式地传递。 就像这样写的。


sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion> =
 Build.VERSION_CODES.JELLY_BEAN_MR2;

if (sEnforceThreadChecking) {
 throw new RuntimeException(throwable);
}


安卓大夫说,"作为安卓的发展对于每个新版本,一些行为甚至外观可能改变 。"所以,我们已经了解了行为和外观的变化,以及这些变化是如何完成了。

总之,androiddoc说"这 attribute(targetSdkVersion) 通知你已经测试了针对目标版本的系统和系统不应启用任何兼容行为,保持你的应用程序与目标版本的forward-compatibility 。 在 web view案例中很清楚。 直到JELLY_BEAN_MR2释放not-main线程上的类方法的web view public调用。 如果Android框架在JELLY_BEAN_MR2设备上抛出一个 RuntimeException,这毫无意义。 它不应该为它的兴趣启用新引入的行为,这会导致致命的后果。 所以,我们要做的就是检查在某些targetSDKversions上是否一切正常。 我们通过设置更高的targetSDKversion来获得像外观增强这样的好处,但它有责任。

后面中提交,在DatePickerDialog构造方法来设置不同的主题,基于当前 targetSDKversion(that i showed 上面) 实际上已经被changed.编辑:免责声明。 但是,我使用了这个例子,因为没有改变逻辑,并且这些代码Fragment清楚地显示了targetSDKversion概念。

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


<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 ): bitmapfactory$options#inbitmap 。图形。

由于 17版本的Android开发工具( ADT ) 有一个新的和非常有用的注解 @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只允许你编译它,但你自己运行它。

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

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

android:targetSdkVersion: 目标sdk版本是设置应用程序的目标API级别。 如果这里属性不能在清单中声明,minSdk版本将是你的TargetSdk版本。 "所有更高版本的API上的应用程序支持安装我们声明为TargetSdk版本"总是如此。 要使应用受限目标,我们需要在清单文件中声明 maxSdkVersion 。。

...