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

评论

从我正在阅读的内容来看,听起来目标SDK版本对应用程序的编译方式没有影响。只是在告诉设备该应用程序正在运行,它不需要启用任何特殊的兼容性功能就可以使您的应用程序正常运行。这是正确的吗?在我看来,直到编译并进行了大量测试之后,您才知道目标SDK版本是什么。为什么编译器不能仅查看您的代码并弄清楚您的应用程序自身兼容哪些平台?

上面的评论者误解了为什么使用targetSDK功能的原因。有关更多详细信息,请参见下面的答案。

接受的答案不正确。请阅读史蒂夫·H的回答。

@tylerl但这不是不正确,而是引用了Google Android文档。我没有添加任何内容。

我认为卡尔的答案是最详细,最精确的。

#1 楼


android:minSdkVersion


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


android:targetSdkVersion


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

具有此属性设置后,该应用程序说它能够在较旧的版本(低至minSdkVersion)上运行,但是经过了明确测试,可以与此处指定的版本一起使用。指定此目标版本将允许平台禁用目标版本不需要的兼容性设置(否则可以启用该功能以保持前向兼容性),或者启用较旧的应用程序不可用的较新功能。这并不意味着您可以为平台的不同版本编程不同的功能,而只是告知平台您已经针对目标版本进行了测试,并且平台不应执行任何额外的工作来保持与目标版本的向前兼容性。 br />
有关更多信息,请参见以下URL:

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

评论


总的来说,您将两者都设置为同一件事。将它们设置为不同的值可能是不寻常的情况。

– jjb
2010年12月31日在6:17

关于jjb的评论:我不同意。有许多很好的理由说明为什么您可以使用不同的minSDK和targetSDK。请参阅我的答案以获取更多详细信息。

–史蒂夫·海利(Steve Haley)
2011-02-14 15:39

#2 楼

OP对问题发表的评论(基本上表明targetSDK不会影响应用的编译)完全是错误的!抱歉,直白地说。

简而言之,这里的目的是声明与minSDK不同的targetSDK:这意味着您使用的是来自更高版本SDK的功能,而不是最低版本,但您已确保向后兼容。换句话说,假设您要使用的功能是最近才引入的,但对您的应用程序而言并不重要。然后,您可以将targetSDK设置为引入此新功能的版本,并将最低版本设置为较低的值,以便每个人仍然可以使用您的应用。大量使用手势检测的应用程序。但是,手势可以识别的每个命令也可以通过按钮或菜单来完成。在这种情况下,手势是“很酷的附加功能”,但不是必需的。因此,您可以将目标sdk设置为7(引入了GestureDetection库时为“ Eclair”),将minimumSDK设置为3级(“ Cupcake”),这样即使是拥有旧手机的人也可以使用您的应用。您要做的就是确保您的应用在尝试使用手势库之前检查了其运行的Android版本,以避免在不存在的情况下尝试使用它。 (当然,这是一个过时的示例,因为几乎没有人拥有v1.5手机,但是有一段时间保持与v1.5的兼容性确实很重要。)如果要使用Gingerbread或Honeycomb的功能,请使用此功能。有些人很快就会获得更新,但是其他人,尤其是使用较旧的硬件的人,可能会在购买新设备之前坚持使用Eclair。这将使您能够使用一些很酷的新功能,但又不会排除您可能的市场的一部分。

Android开发者博客上有一篇非常好的文章,内容涉及如何使用此功能,尤其是我上面提到的如何设计“在使用前检查功能是否存在”代码。 OP:我写这篇文章主要是为了将来碰巧遇到这个问题的任何人的利益,因为我意识到您的问题是很久以前提出的。

评论


您能否提供准确的解释,说明targetSDKversion如何影响应用程序的编译?因为编译版本还是您需要设置的另一种配置。先感谢您

– hnviet
2011年8月27日15:23



我认为Steve在清单xml属性android:targetSdkVersion(没有确切的说法)与驻留在project.properties文件中的target属性之间感到困惑,后者代表应该编译什么代码。我再说一遍,xml attr targetSdkVersion没有真正的含义!!!

– AlikElzin-kilaka
2012年2月12日在16:04

@kilaka您的评论有一半是有效的,但另一半是错误的。我假设某人在XML和project.properties中使用了相同的值(也可以通过在Eclipse中右键单击-> properties访问),所以您正确地指出他们存储在不同的位置。但是,Android Market无疑会关心您在xml属性targetSdkVersion中输入的值。例如,它在确定是否应为Honeycomb及更高版本的应用程序使用ActionBar或兼容性菜单时使用。

–史蒂夫·海利(Steve Haley)
2012年2月15日在13:14

@Nate我无法说出这种“复杂代码”使运行时变慢多少,但我确实认为,在代码复杂度方面,拆分和使用多个APK会更糟。现在,您必须记住注释/注释掉或在源代码管理中的更多分支中合并,然后才能进行每次导出。在去年10月举行的一次Android会议上,他们说他们推出了多APK系统作为一种让步,但很高兴很少有人使用它。

–史蒂夫·海利(Steve Haley)
2012年2月20日在16:16

但是处理多个版本是版本控制系统的主要作用。这就是开发人员所熟悉的(大多数软件,无论是否为移动设备,针对不同平台发布的版本都略有不同)。这个Android的“功能”并没有降低复杂性。它只是将其推送到正在运行的应用程序中,并且正如该线程所证明的那样,造成混乱。当然,谷歌将为很少有人使用它而感到高兴……这有助于他们说:“瞧瞧,我们一开始就忽略了这一点是正确的”。另外,有些人不使用它,因为他们还不知道它的存在。

–内特
2012年2月23日在9:50



#3 楼

当您设置targetSdkVersion =“ xx”时,即表示您的应用程序在API级别xx下可以正常运行(例如,已经过全面成功测试)。 xx将自动应用兼容性代码以支持您可能依赖的任何功能,这些功能可能在API级别xx或之前可用,但现在在该Android版本的更高级别已作废。如果使用的是在xx级或之前已过时的任何功能,则更高版本的API级别(不再包含这些功能)的操作系统版本将不会自动应用兼容性代码来支持这些用途。在这种情况下,您自己的代码必须具有测试API级别的特殊情况子句,并且,如果检测到的操作系统级别是更高的级别,而不再具有给定的API功能,则您的代码必须使用正在运行的操作系统的可用替代功能API级别。

如果这样做失败,则可能根本不会出现通常会触发代码内事件的某些界面功能,并且您可能会缺少用户需要触发这些事件的关键界面功能,并且来访问其功能(如下面的示例所示)。如其他答案所述,如果要使用最初定义为比minSdkVersion更高的API级别定义的某些API功能,则可以将targetSdkVersion设置为高于minSdkVersion。 ,并已采取措施以确保您的代码能够以比targetSdkVersion更低的级别检测和处理这些功能的缺失。

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

@TargetApi(nn)


告诉编译器该指令范围内的代码(在方法或类之前)已被执行。在调用任何依赖于至少具有该API级别的方法之前编写,以测试API级别至少为nn。例如,以下代码定义了可从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();
    }
}


即使您未使用高于minSdkVersion的API级别的任何功能,也可能要声明一个较高的targetSdkVersion,如果您已在较高级别进行了测试,并且一切正常。这仅仅是为了避免访问旨在从目标级别降至最低级别的兼容性代码的开销,因为您已经(通过测试)确认不需要进行此类更改。

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

minSdkVersion声明设备的OS版本至少具有该API级别以运行您的应用。这会影响当它们在Google Play应用商店(以及其他应用商店)中时,哪些设备能够查看和下载您的应用。这是一种说明您的应用程序依赖于在该级别建立的OS(API或其他)功能的方法,而对于没有这些功能的情况,尚无可接受的方法。使用minSdkVersion来确保存在与API不相关的功能的示例是将minSdkVersion设置为8,以确保您的应用仅在启用了JIT的Dalvik解释器上运行(因为引入了JIT)到API级别8的Android解释器)。由于启用JIT的解释器的性能可能是缺少该功能的解释器的五倍,因此,如果您的应用大量使用处理器,那么您可能需要API级8或更高级别,以确保足够的性能。 br />

评论


感谢您提供有关使用TargetApi指令的说明。

–samir105
16年5月12日在22:39

@Carl是否意味着我可以始终将targetSdkVersion设置为高于minSdkVersion的任何版本(尤其是获得那些UI增强),而无需进行任何测试(本身),只要我限制我的代码库仅使用minSdkVersion中可用的API ?

– Damilola Olowookere
17-4-15的0:37



Olowookere Emmanuel:如果我对您的理解正确,那么不,那并不意味着那样。正如我的回答所言:“如果您使用的任何功能在xx级或之前已过时,兼容性代码将不会在更高API级的操作系统版本中自动应用。”因此,如果您的代码使用的功能在API级别8中可用,而该功能在级别10时已过时,那么如果将targetSdkVersion提升到10以上,则将没有兼容代码可用于调整该功能已升级到新的操作系统级别。

–卡尔
17年5月3日,下午5:35

(续):鉴于,如果将targetSdkVersion保留在第8级,则虽然您将无法使用在更高级别引入的功能,但是将应用兼容代码,以允许您在运行时使用第8级功能更高的操作系统级别。

–卡尔
17年5月3日,下午5:39

(继续):这样考虑:假设您在可用的最高Android级别为8时编写了一些代码,并将targetSdkVersion设置为8(因为当时是最高级别)。现在,出现了一些新版本的Android,并且您使用的某些第8级功能不可用。仍然拥有旧APK的用户应该不会遇到错误,应该吗?因此,为确保它们不会,兼容性代码将自动应用以调整您的旧API调用,以在用户运行较新版本的OS时调用它们时做一些合理的事情。

–卡尔
17年5月4日在6:45



#4 楼

始终可以通过示例更好地实现一个概念。在理解Android框架源代码并进行一些实验之前,即使在阅读了Android开发人员网站中的所有文档以及相关的stackoverflow线程之后,我还是难以理解这些概念。我将分享两个示例,这些示例有助于我充分理解这些概念。

DatePickerDialog会根据您放入AndroidManifest.xml文件的targetSDKversion(<uses-sdk android:targetSdkVersion="INTEGER_VALUE"/>)的级别而看起来有所不同。如果将值设置为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并设置了不同的主题。这种代码片段(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,这是胡说八道。它只是不应出于自己的兴趣启用新引入的行为,否则会导致致命的后果。因此,我们要做的是检查在某些targetSDK版本上是否一切正常。通过设置更高的targetSDKversion,我们可以获得外观增强的好处,但是它带有责任感。

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

评论


“通过设置更高的targetSDKversion,我们可以获得诸如外观增强之类的好处,但它带有责任感。”如果他们在文档中提到了这一行,我就不会在寻找它。

– Manish Kumar Sharma
15年6月18日在5:34

@김준호我有两个问题:1.)在上面的日期选择器示例中,如果将targetSdkVersion设置为10或更低,并在运行最新Android(例如API 22)的设备上运行该应用,日期选择器仍会像旧版本在左图上? 2)这是否意味着我可以始终将targetSdkVersion设置为高于minSdkVersion的任何版本(例如,从更高的API获得UI增强功能,如清晰的日期选择器),而无需进行任何测试(本身),只要我限制我的代码库只使用minSdkVersion中可用的API?

– Damilola Olowookere
17年4月15日在0:43

@Olowookere 1)是的。只是运行它。 2)如果目标版本高于minSDKVersion,则可以将targetSDKVersion设置为任何所需的版本。但是您仍然需要测试它是否可以在目标版本上正常运行。无论您是否坚持使用minSDKVersion api,都没有关系。考虑一下DatePicker示例。

–김준호
17-4-16在15:29



考虑一下您将最小版本14和目标sdk版本设置为16的情况,而您只使用了14或更低版本的api。假设您使用了API级别1中引入的TextView。会发生什么?

–김준호
17年4月16日在15:48

@김준호谢谢。但是对于您的第二个答案,我感到困惑。如果我的代码仅在minSdkVersion中使用API​​,而我的目标是更高的SDK,为什么需要测试?考虑一下DatePicker示例,高targetSdkVersion仅改善了DatePicker小部件的外观,并且没有任何中断,因为我没有在API中使用任何高于minSdkVersion的代码。我只想要更高的targetSdkVersion,因为我想要小部件的新外观,而不是我想使用更高API引入的新功能

– Damilola Olowookere
17年4月17日在11:52

#5 楼

对于需要摘要的用户,在您的应用程序支持之前,
是最低版本。如果您的设备具有较低版本的android,则应用将无法安装。

,同时,

android:minSdkVersion


是应用程序的API级别设计运行。意味着,您的手机系统无需使用任何兼容性行为即可保持向前兼容性,因为您对此API进行了测试。

您的应用仍可在高于给定targetSdkVersion的Android版本上运行,但会出现android兼容行为。 >
如果您设备的API版本更高,则不会安装该应用。就是这是允许您安装应用程序的最大API。

ie。对于MinSDK -4,maxSDK-8,targetSDK-8我的应用程序最低可以使用1.6,但我也使用了仅在2.2中受支持的功能,如果将其安装在2.2设备上,该功能将可见。另外,对于maxSDK-8,此应用程序无法使用API​​> 8安装在手机上。现在已经很好地解释了。在这里检查

评论


“是您的应用继承功能的最高版本。” :这是错误的。这是您的应用继承功能的最低版本,即包含您的应用所使用的必需功能的第一个版本。

– RichieHH
13-10-15在8:44

英语是棘手的语言。阅读答案中给出的示例。我认为我在那里有意义。 :)

–大班
14年7月16日在12:31

我不是在书呆子,英语是该组的支持语言。棘手或不说其“该应用程序支持功能的最大版本”不仅是错误的:完全180度错误。它是FIRST或最低版本,无需使用后备兼容模式/库即可支持应用程序的所有预期功能。

– RichieHH
2014年7月18日在21:12



#6 楼

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

<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只是允许您对其进行编译,但要自己承担风险。

评论


我对此感到困惑。如果稍后在带有sdk 10的系统中运行您的应用程序会怎样?

– Fran Marzoa
2012年11月22日14:03

它将输出options.inBitmap语句和应用程序应该可以正常工作。

– NinjaCoder
2014年2月25日在20:50

#7 楼

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

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

如果未在清单中声明此属性,则minSdk版本将为您的TargetSdk版本。 “在我们声明为TargetSdk版本的所有更高版本的API上安装应用程序支持”始终是正确的。为了使应用程序受限制,我们需要在清单文件中声明maxSdkVersion ...

#8 楼

如果您制作的应用程序需要危险的权限,并将targetSDK设置为23或更高,则应小心。如果不检查运行时的权限,则将获得SecurityException,并且如果您在try块中使用代码,例如打开的摄像头,则不检查logcat可能很难检测到错误。

#9 楼

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