Android Min SDK版本与目标SDK版本

Mic*_*llo 439 eclipse android

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

Ste*_*ley 867

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

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

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

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

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

对于OP:我写这篇文章主要是为了将来偶然遇到这个问题的人,因为我意识到你的问题很久以前就被问过了.

  • 我认为Steve在清单xml属性**android:targetSdkVersion**(没有真正的说法)和驻留在project.properties文件中的**target**属性之间混淆,该文件代表编译代码的内容.我再说一遍,xml attr targetSdkVersion没有实际意义! (9认同)
  • @kilaka你评论的一半是有效的,但另一半是完全错误的.我假设有人在XML和project.properties中使用相同的值(也可以通过Eclipse中的右键单击 - >属性访问),所以你指出它们存储在不同的地方是正确的.但是,Android Market肯定会关注你在xml属性targetSdkVersion中放置的值.例如,它在确定您是否应该具有ActionBar或Honeycomb及以上应用程序的兼容性菜单时使用它. (3认同)
  • 能否请您准确解释targetSDKversion如何影响应用程序的编译?因为编译版本又是您需要设置的另一种配置.先感谢您 (2认同)
  • @Nate我不能说这个"复杂的代码"使运行时速度慢多少,但我确实认为在代码复杂性方面分割和使用多个APK更糟糕.现在你必须记住在进行/退出或通过源代码管理中的更多分支进行合并,然后才能进行每次导出.在去年十月举行的Android大会上,他们说他们推出了多个APK系统作为让步,但很高兴很少有人使用它. (2认同)
  • 但处理多个版本是为其制作的版本控制系统.这是开发人员熟悉的(大多数软件,移动与否,为不同平台发布略有不同的版本).这个Android"功能"并没有降低复杂性.它只是将它推入正在运行的应用程序中,正如这个线程所证明的那样,造成了混乱.当然,谷歌会很高兴很少有人在使用它...这有助于他们说,"看,我们首先做出这个疏忽是正确的".另外,有些人不使用它,因为他们还不知道它存在. (2认同)

Vik*_*dar 135

安卓的minSdkVersion

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

机器人:targetSdkVersion

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

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

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

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

  • 关于jjb的评论:我不同意.有很多很好的理由可以让你拥有不同的minSDK和targetSDK.有关详细信息,请参阅我的回答 (66认同)

Car*_*arl 97

当您设置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)
Run Code Online (Sandbox Code Playgroud)

告诉编译器在调用依赖于至少具有该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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

这取决于宣布targetSdkVersion将是具有targetSdkVersion小于11,当这些应用不仅在API 11和更高的运行的应用程序的状态栏上显示的三个垂直点菜单按钮UI功能的一个例子.如果您的应用程序有10或低于targetSdkVersion,假设您的应用程序的界面取决于一个专门的菜单按钮的存在,所以有三个点的按钮出现取较早的专用硬件和/或屏幕版本的地方当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或更高级别以确保足够的性能.


김준호*_*김준호 50

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

一个DatePickerDialog将根据你把在AndroidManifest.xml文件的targetSDKversion(水平会有所不同<uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>).如果将值设置为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();       
    }
}
Run Code Online (Sandbox Code Playgroud)

而且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>
Run Code Online (Sandbox Code Playgroud)


而已.这就是我需要测试的所有代码.

当您看到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);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,框架获取当前的targetSDKversion并设置不同的主题.这种代码片段(getApplicationInfo().targetSdkVersion >= SOME_VERSION)可以在Android框架中找到.

另一个例子是关于WebView类.Webview类的公共方法应该在主线程上调用,如果没有,运行时系统会RuntimeException在设置targetSDKversion 18或更高时抛出一个.可以使用其源代码清楚地传递此行为.它就是这样写的.

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

if (sEnforceThreadChecking) {
    throw new RuntimeException(throwable);
}
Run Code Online (Sandbox Code Playgroud)


Android文档称," 随着Android随着每个新版本的发展,一些行为甚至外观都可能发生变化." 因此,我们看到了行为和外观的变化,以及如何实现这种变化.

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

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

  • "我们通过设置更高的targetSDKversion获得外观增强等好处,但它带来了责任感." 如果他们在文档中提到过这一行,我就不会寻找它. (2认同)

Dar*_*pan 21

对于那些想要总结的人,

android:minSdkVersion
Run Code Online (Sandbox Code Playgroud)

是您的应用程序支持的最低版本.如果您的设备有较低版本的Android,应用程序将无法安装.

而,

android:targetSdkVersion
Run Code Online (Sandbox Code Playgroud)

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

您的应用程序仍然会在比给定版本更高的Android版本上运行,targetSdkVersion但Android兼容性行为将会启动.

赠品 -

android:maxSdkVersion

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

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

在撰写此答案时,Android文档在解释它时没有做得很好.现在它得到了很好的解释.在这里查看


Win*_*der 9

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

<uses-sdk
            android:minSdkVersion="10"
            android:targetSdkVersion="15" />
Run Code Online (Sandbox Code Playgroud)

.

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**
        //...
    }
Run Code Online (Sandbox Code Playgroud)

你得到编译错误:

字段需要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**
            //...
      }
    }
Run Code Online (Sandbox Code Playgroud)

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

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