在开发 Android 应用时,"Min SDK 版本"和 "Target SDK 版本" 有什么区别?如果 Min 和 Target 版本不同,Eclipse 就无法创建新项目!
在开发 Android 应用时,"Min SDK 版本"和 "Target SDK 版本" 有什么区别?如果 Min 和 Target 版本不同,Eclipse 就无法创建新项目!
OP在评论中提到的问题(基本上是说targetSDK不影响应用程序的编译)完全是错误的!抱歉直言。
简而言之,声明与minSDK不同的targetSDK的目的是:意味着您正在使用比最低级别更高级别的SDK中的功能,但您已经确保了向后兼容性。换句话说,想象一下,您想使用最近引入的一个功能,但这对您的应用程序并不重要。然后,您将设置targetSDK为引入此新功能的版本,将minimum设置为较低的版本,以便每个人都可以使用您的应用程序。
举个例子,假设您正在编写一个广泛使用手势检测的应用程序。但是,手势可以识别的每个命令也可以通过按钮或菜单完成。在这种情况下,手势是“很棒的额外功能”,但并非必需品。因此,您将将target sdk设置为7(“Eclair”当GestureDetection库被引入时),并将minimumSDK设置为级别3(“Cupcake”),以便即使拥有非常旧的手机的人也可以使用您的应用程序。您只需要确保您的应用程序在尝试使用手势库之前检查其运行的Android版本,以避免在不存在该库时尝试使用它。(诚然,这是一个过时的例子,因为几乎没有人仍然拥有v1.5手机,但是在维护与v1.5的兼容性非常重要的时候曾经存在这样的时候。)
为了举例说明,如果您想要使用Gingerbread或Honeycomb中的某个功能,则可以使用此功能。一些人很快就会得到更新,但许多其他人,尤其是那些使用老旧硬件的人,在购买新设备之前可能会一直停留在Eclair上。这将使您能够使用一些很酷的新功能,但不会排除您可能的部分市场。android:minSdkVersion
一个整数,表示应用程序运行所需的最低API级别。如果系统的API级别低于此属性中指定的值,则Android系统将阻止用户安装应用程序。您应该始终声明此属性。
android:targetSdkVersion
一个整数,表示应用程序目标API级别。
设置了此属性后,应用程序表示它能够运行在旧版本(至少是minSdkVersion),但已明确测试过与此处指定的版本可以正常工作。指定这个目标版本允许平台禁用不需要为目标版本保持向前兼容性而开启的兼容性设置,或者启用老版本应用程序无法使用的新功能。这并不意味着您可以为平台的不同版本编写不同的功能 - 它仅仅是告知平台您已经针对目标版本进行了测试,平台不应该执行任何额外的工作来保持与目标版本的向前兼容性。
更多信息请参考以下网址:
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
@TargetApi(nn)
使用这个指令可以告诉编译器在调用任何至少需要这个API级别的方法之前,该指令所在范围内的代码已经被编写来测试至少为nn的API级别。例如,以下代码定义了一个方法,可以从具有最低SDK版本小于11且目标SDK版本为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();
}
}
如果您已经在更高的目标 SDK 版本上测试过且一切运作正常,即使您并未使用高于 minSdkVersion 的 API 级别中的任何功能,可能还需要声明更高的 targetSdkVersion。这只是为了避免访问兼容性代码以从目标级别适应到最小级别的开销,因为您已经通过测试确认不需要进行此类适应。基于您在AndroidManifest.xml文件的targetSdkVersion(<uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>
)中设置的级别,DatePickerDialog的外观会有所不同。如果您将值设置为10或更低,则您的DatePickerDialog将如左图所示。另一方面,如果您将值设置为11或更高,则DatePickerDialog将看起来像右边的图片,使用完全相同的代码。
我用来创建此示例的代码非常简单。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并设置不同的主题。在Android框架中,可以随处找到这种代码片段(getApplicationInfo().targetSdkVersion >= SOME_VERSION
)。
另一个例子是关于WebView类的。Webview类的公共方法应在主线程上调用,否则,当您设置targetSDKversion为18或更高版本时,运行时系统会抛出RuntimeException
。这种行为可以通过其源代码清楚地传达。它就是这样写的。
sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
Build.VERSION_CODES.JELLY_BEAN_MR2;
if (sEnforceThreadChecking) {
throw new RuntimeException(throwable);
}
Android文档中指出:“随着每个新版本的推出,一些行为和外观可能会发生变化。” 因此,我们研究了行为和外观的变化以及如何实现这种变化。
总之,Android文档表示:“此属性(targetSdkVersion)通知系统您已针对目标版本进行了测试,并且系统不应启用任何兼容性行为以保持您的应用程序与目标版本的向前兼容性。” 在WebView案例中非常清楚。在JELLY_BEAN_MR2发布之前,可以调用WebView类的公共方法而不会报错。如果Android框架在JELLY_BEAN_MR2设备上抛出RuntimeException,则是无意义的。它只是不应该为其利益启用新引入的行为,这将导致灾难性的结果。因此,我们必须检查某些targetSDKversions上是否一切正常。通过设置更高的targetSDKversion,我们可以获得外观增强等好处,但也需要承担责任。
编辑: 免责声明。 上面展示的基于当前targetSDKversion设置不同主题的DatePickerDialog构造函数实际上已在后续提交中进行了更改。尽管如此,我仍使用了该示例,因为逻辑并未更改,并且这些代码片段清楚地显示了targetSDKversion的概念。
对于那些想要摘要的人,
android:minSdkVersion
这是您的应用程序所支持的最低版本。如果您的设备运行较低版本的Android,则应用程序将无法安装。
然而,
android:targetSdkVersion
API级别是您的应用程序设计运行的最高级别。这意味着,您的手机系统不需要使用任何兼容性行为来保持向前兼容性,因为您已经测试了该API级别。
即使给定的targetSdkVersion
低于Android版本,您的应用程序仍将在更高版本的Android上运行,但会触发Android兼容性行为。
额外提供 -
android:maxSdkVersion
如果您的设备API版本更高,则应用程序将无法安装。也就是说,这是您允许应用程序安装的最高API。
例如,对于MinSDK-4、MaxSDK-8、TargetSDK-8,我的应用程序将在最低1.6上工作,但我还使用了仅在2.2上支持的功能,如果安装在2.2设备上,这些功能将可见。此外,对于MaxSDK-8,该应用程序将无法安装在使用API > 8的手机上。
撰写本答案时,Android文档并未很好地解释它。现在它已经非常清楚了。 在此查看
如果你遇到一些编译错误,例如:
<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**
//...
}
}
现在没有编译错误,并且它将运行!
编辑:这将导致低于11的API级别上运行时错误。在11或更高版本上,它将无问题运行。因此,您必须确保在由版本检查保护的执行路径上调用此方法。TargetApi只允许您进行编译,但自行承担风险。
android:minSdkVersion
和android:targetSdkVersion
都是我们需要在Android清单文件中声明的整数值,但它们具有不同的属性。
android:minSdkVersion:
这是运行Android应用程序所需的最低API级别。如果我们将同一应用程序安装在较低的API版本上,则会出现解析器错误,以及应用程序不支持问题。
android:targetSdkVersion:
目标SDK版本是设置应用程序的目标API级别。如果在清单中未声明此属性,则minSdk版本将是您的TargetSdk版本。这始终是真实的:“应用程序支持在我们声明为TargetSdk版本的所有更高版本的API上安装”。要使应用程序成为有限目标,我们需要在清单文件中声明maxSdkVersion...
如果您正在开发需要危险权限并将targetSDK设置为23或更高版本的应用程序,那么您需要小心谨慎。如果您在运行时不检查权限,则会收到SecurityException异常。例如,如果您在try块中使用打开摄像头的代码,如果不检查logcat,则很难检测错误。
目标 SDK 是您想要针对的版本,而最小 SDK 则是最低版本。