繁体   English   中英

Android Min SDK版本与目标SDK版本

[英]Android Min SDK Version vs. Target SDK Version

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

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

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

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

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

Android开发人员的博客中有一篇非常好的文章介绍了如何使用此功能,特别是如何设计上面提到的“检查使用它之前存在的功能”代码。

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

安卓的minSdkVersion

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

机器人:targetSdkVersion

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

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

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

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

当您设置targetSdkVersion =“xx”时,您将证明您的应用程序在API级别xx上正常工作(例如,已经过彻底和成功测试)。

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

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

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

如其他答案中所述,如果您想使用最初在比minSdkVersion更高的API级别定义的API功能,则可以将targetSdkVersion设置为高于minSdkVersion,并且已采取措施确保您的代码可以检测并处理这些功能的缺失比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如果你已经在这个更高的水平测试,一切正常,即使您没有使用从比你的minSdkVersion更高的API级别的任何功能。 这只是为了避免访问旨在从目标级别调整到最低级别的兼容性代码的开销,因为您已经确认(通过测试)不需要这样的调整。

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

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

使用的minSdkVersion确保 API相关的一个特征的存在的一个例子是对的minSdkVersion为了设置为8,以确保您的应用程序将只在Dalvik解释的启用JIT版本上运行(因为JIT介绍到API级别的Android解释器8)。 由于启用JIT的解释器的性能可能是缺少该功能的解释器的五倍,如果您的应用程序大量使用处理器,那么您可能需要API级别8或更高级别以确保足够的性能。

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

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

使用targetSDKversion 10或更低版本的DatePickerDialog使用targetSDKversion 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并设置不同的主题。 这种代码片段( getApplicationInfo().targetSdkVersion >= SOME_VERSION )可以在Android框架中找到。

另一个例子是关于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)通知系统您已针对目标版本进行了测试,系统不应启用任何兼容性行为来维持应用程序与目标版本的向前兼容性。 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:maxSdkVersion

如果您的设备的API版本较高,则不会安装应用。 IE浏览器。 这是您允许应用安装的最高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**
            //...
      }
    }

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM