Android Min SDK版本与目标SDK版本

时间:2010-12-31 05:24:59

标签: android eclipse

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

9 个答案:

答案 0 :(得分:865)

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

简而言之,此处的目的是从minSDK声明不同的targetSDK:这意味着您使用的是比最低级别SDK更高级别的SDK,但 确保了向后兼容性 即可。换句话说,假设您想要使用最近才引入的功能,但这对您的应用程序并不重要。然后,您可以将targetSDK设置为引入此新功能的版本,将最小值设置为较低的值,以便每个人都可以使用您的应用。

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

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

Android developer's blog中有一篇非常好的关于如何使用此功能的文章,特别是如何设计上面提到的“在使用之前检查功能”代码。

致OP:我写这篇文章的主要是为了将来碰巧遇到这个问题的人,因为我意识到很久以前你的问题已被提出。

答案 1 :(得分:135)

  

机器人:的minSdkVersion

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

  

android:targetSdkVersion

指定应用程序所针对的API级别的整数。

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

有关详细信息,请参阅以下网址:

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

答案 2 :(得分:96)

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

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

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

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

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

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

@TargetApi(nn)

告诉编译器,在调用任何依赖于至少具有的方法之前,已编写该指令范围内的代码(将在方法或类之前)以测试至少nn的API级别那个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();
    }
}

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

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

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

使用minSdkVersion确保 API相关的功能的存在的示例是将minSdkVersion设置为8,以确保您的应用仅在启用JIT的情况下运行Dalvik解释器的版本(因为JIT是在API级别8引入Android解释器)。由于启用JIT的解释器的性能可能是缺少该功能的解释器的五倍,如果您的应用程序大量使用处理器,那么您可能需要API级别8或更高级别以确保足够的性能。 / p>

答案 3 :(得分:50)

可以通过示例更好地提供概念,始终 。在深入研究Android框架源代码并进行一些实验之前,我很难理解这些概念,即使在阅读了Android开发者网站中的所有文档之后。相关的stackoverflow线程。我将分享两个帮助我完全理解这些概念的例子。

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

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>


就是这样。这真的是我需要测试的所有代码。

当你看到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或更高时,运行时系统会抛出RuntimeExceptionits source code可以清楚地传达此行为。它就是这样写的。

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

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


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

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

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

答案 4 :(得分:21)

对于那些想要摘要的人,

android:minSdkVersion

是您的应用程序支持之前的最低版本。如果您的设备具有较低版本的Android,则无法安装应用。

而,

android:targetSdkVersion

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

您的应用仍将在高于给定targetSdkVersion的Android版本上运行,但Android兼容性行为将会启动。

免费赠品 -

android:maxSdkVersion

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

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

在撰写此答案时,Android文档在解释它方面做得不是很好。现在它得到了很好的解释。 Check it here

答案 5 :(得分:9)

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

<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 $选项#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只允许你编译它,但你自己承担风险。

答案 6 :(得分:1)

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

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

android:targetSdkVersion: 目标sdk版本是设置应用的目标API级别。如果未在清单中声明此属性,则minSdk版本将是您的TargetSdk版本。这始终是“app支持在我们声明为TargetSdk版本的所有更高版本的API上安装”。要使app限制目标,我们需要在清单文件中声明maxSdkVersion ...

答案 7 :(得分:1)

目标sdk是要定位的版本,最小sdk是最低版本。

答案 8 :(得分:0)

如果您制作的应用需要dangerous permissions并将targetSDK设置为23或更高,则应该小心。如果您没有检查运行时的权限,您将获得SecurityException,如果您在try块中使用代码,例如打开相机,如果您不检查logcat,则很难检测到错误。