在为Android开发应用程序时,Min和Target SDK版本有什么不同?Eclipse不允许我创建新项目,除非最小版本和目标版本相同!
当前回答
如果你正在制作需要危险权限的应用程序,并将targetSDK设置为23或更高,你应该小心。如果你在运行时不检查权限,你会得到一个SecurityException,如果你在一个try块中使用代码,例如open camera,如果你不检查logcat,就很难发现错误。
其他回答
如果你得到一些编译错误,例如:
<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): # inBitmap android.graphics.BitmapFactory美元选项
自从第17版的Android开发工具(ADT),有一个新的和非常有用的注释@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**
//...
}
}
现在没有编译错误,它将运行!
EDIT:这将导致API级别低于11的运行时错误。在11或更高版本上,它运行起来没有问题。因此,必须确保在版本检查保护的执行路径上调用此方法。TargetApi只允许你编译它,但是你要自担风险。
Target sdk是你想要的目标版本,而min sdk是最小的一个。
android: minSdkVersion
一个整数,指定应用程序运行所需的最小API级别。如果系统的API级别低于此属性中指定的值,Android系统将阻止用户安装应用程序。您应该始终声明此属性。
android: targetSdkVersion
一个整数,指定应用程序的目标API级别。
With this attribute set, the application says that it is able to run on older versions (down to minSdkVersion), but was explicitly tested to work with the version specified here. Specifying this target version allows the platform to disable compatibility settings that are not required for the target version (which may otherwise be turned on in order to maintain forward-compatibility) or enable newer features that are not available to older applications. This does not mean that you can program different features for different versions of the platform—it simply informs the platform that you have tested against the target version and the platform should not perform any extra work to maintain forward-compatibility with the target version.
更多信息请参考这个URL:
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
一个概念总是可以用例子更好地表达。我很难理解这些概念,直到我深入研究Android框架源代码,并做了一些实验,甚至在阅读了Android开发人员网站和相关stackoverflow线程中的所有文档之后。我将分享两个例子,它们帮助我充分理解这些概念。
一个DatePickerDialog将根据你放在AndroidManifest.xml文件的targetSDKversion(<use -sdk android: targetSDKversion ="INTEGER_VALUE"/>)中的级别看起来不同。如果您将值设置为10或更低,您的DatePickerDialog将看起来像左边。另一方面,如果您将值设置为11或更高,则DatePickerDialog将看起来是正确的,具有完全相同的代码。
我用来创建这个示例的代码非常简单。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的每一个新版本的发展,一些行为甚至外观可能会发生变化。”我们已经研究了行为和外表的变化,以及这些变化是如何实现的。
In summary, the Android doc says "This attribute(targetSdkVersion) informs the system that you have tested against the target version and the system should not enable any compatibility behaviors to maintain your app's forward-compatibility with the target version.". This is really clear with WebView case. It was OK until JELLY_BEAN_MR2 released to call WebView class's public method on not-main thread. It is nonsense if Android framework throws a RuntimeException on JELLY_BEAN_MR2 devices. It just should not enable newly introduced behaviors for its interest, which cause fatal result. So, what we have to do is to check whether everything is OK on certain targetSDKversions. We get benefit like appearance enhancement with setting higher targetSDKversion, but it comes with responsibility.
编辑: 免责声明。DatePickerDialog构造函数根据当前targetSDKversion(上面所示)设置不同的主题,实际上在稍后的提交中已经更改。尽管如此,我还是使用了那个例子,因为逻辑没有改变,而且那些代码片段清楚地显示了targetSDKversion概念。
OP对这个问题的评论(基本上是说targetSDK不会影响应用程序的编译)是完全错误的!很抱歉我这么直率。
In short, here is the purpose to declaring a different targetSDK from the minSDK: It means you are using features from a higher level SDK than your minimum, but you have ensured backwards compatibility. In other words, imagine that you want to use a feature that was only recently introduced, but that isn't critical to your application. You would then set the targetSDK to the version where this new feature was introduced and the minimum to something lower so that everyone could still use your app.
To give an example, let's say you're writing an app that makes extensive use of gesture detection. However, every command that can be recognised by a gesture can also be done by a button or from the menu. In this case, gestures are a 'cool extra' but aren't required. Therefore you would set the target sdk to 7 ("Eclair" when the GestureDetection library was introduced), and the minimumSDK to level 3 ("Cupcake") so that even people with really old phones could use your app. All you'd have to do is make sure that your app checked the version of Android it was running on before trying to use the gesture library, to avoid trying to use it if it didn't exist. (Admittedly this is a dated example since hardly anyone still has a v1.5 phone, but there was a time when maintaining compatibility with v1.5 was really important.)
再举一个例子,如果你想使用Gingerbread或Honeycomb的特性,你可以使用这个。一些人很快就会得到更新,但许多人,尤其是使用较老硬件的人,可能会继续使用Eclair,直到他们购买新设备。这将允许你使用一些很酷的新功能,但不会排除部分可能的市场。
Android开发人员的博客上有一篇关于如何使用这个功能的非常好的文章,特别是如何设计我上面提到的“在使用之前检查功能是否存在”的代码。
致OP:我写这篇文章主要是为了让将来偶然遇到这个问题的人受益,因为我意识到你的问题很久以前就被问过了。
推荐文章
- 自动适合Android的TextView
- 无法创建Android虚拟设备
- 如何在Android中获得一个RadioGroup的选定索引
- 如何分配文本大小在sp值使用java代码
- Manifest合并失败:uses-sdk:minSdkVersion 14
- 为什么Android工作室说“等待调试器”如果我不调试?
- 如何检查我的EditText字段是否为空?
- Android从图库中选择图像
- 如何使用Eclipse比较两个文件?Eclipse是否提供了任何选项?
- 后台任务,进度对话框,方向改变-有任何100%工作的解决方案吗?
- Android:垂直对齐多行EditText(文本区域)
- Android无尽列表
- Android room persistent: AppDatabase_Impl不存在
- 错误:执行失败的任务':app:compileDebugKotlin'。>编译错误。详细信息请参见日志
- 在Android中使用URI生成器或使用变量创建URL