@TargetAPI

1.Annotation
Annotation继承自java.lang.annotation.Annotation的类,用于向程序分析工具或虚拟机提供package class field methed 等方面的信息。Annotation 提供了一条与程序元素关联任何信息或者任何元数据(metadata)的途径。从某些方面看, annotation 就像修饰符一样被使用,并应用于包、类 型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在annotation的“name=value”结构对中。 annotation 类型是一种接口,能够通过java反射API的方式提供对其信息的访问。
annotaion 不影响程序代码的执行,无论增加、删除 annotation ,代码都始终如一的执行。
annotaion 与其他类的主要不同之处在于其使用方式;只要按照“@+annotation类型名称+(..逗号分割的name-value对...)”的组成语法,写在需要的地方。其中成员可以按照任何的顺序。如果 annotation 类型定义了某个成员的默认值,则这个成员可以被省略,eg.@Override。

annotation 方式写程序简短实用易维护,所以越来越成为主流。

2.Android lint
Android lint是一个代码扫描工具,能够帮助我们识别代码结构存在的问题,比如使用了高于minSdk的api。


3.@TargetAPI Annotation

@TargetAPI 对应android.annotation.TargetApi,与它相似的注解还有@SuppressLint,作用都是告诉编译器:你可以忽略掉lint错误了,我用高于minSdk的api又咋滴?要你管啊~我不怕啊^_^

As you can see, lint now has a database of the full Android API such that it knows precisely which version each API call was introduced in. If it detects that you are attempting to call a method which is not available in all versions you are trying to support, it will warn you with messages like the above.

正如你所看到的, lint现 在有完整的Android API的一个数据库,这样它清楚地知道哪个版本的哪一个API调用了。如果它检测到你正试图调用一个方法不是在所有版本都可用,那么它将提醒给你上面的消息。

Of course, if you're building your project with the same version of Android as your oldest support version, the compiler will complain if it finds an API call it can't resolve. However, that approach has some downsides. In particular, you may want to access newer APIs on platforms where they are available. If you're compiling against the oldest version of the platform, you would need to use reflection to access all the new APIs, which can be really cumbersome, especially if you have a lot of code using the newer APIs.
The way most developers get around this is to actually use a newer build target, which means you can access all the new APIs directly. You then add some code checks to make sure that the code path which calls the newer APIs is only reached when running on a version which supports <span style="font-family: Arial, Helvetica, sans-serif;"> </span>


当然,如果您编译的项目的版本和支持的最低支持的版本相同, 编译器会提示找不到相关API。然而,这种方法有一些缺点。特别是,您可能希望访问新的平台上可用的api。如果你对老版本的编译平台,您将需要使用反射来访问所有的新api,可真的麻烦,特别是如果你有很多的代码使用新的api。
实际上大多数开发人员解决这个问题的方法是使用更高的版本来编译这个项目,这意味着您可以直接访问所有的新api。然后添加一些代码检查,以确保调用的代码路径上运行时达成的新api只是一个版本支持它。


However, when you do this you run the risk of accidentally calling newer APIs, and that's what Lint now helps you detect.
What about code where you are deliberately calling newer APIs from a class you know will only be loaded in the right circumstances? In that case you can "mark" the code as targeting a newer version of the API. Simply annotate the code with the new @TargetApiannotation:


然而,当你这么做了,那么在低版本上调用新的api可能会有崩溃的风险, 这就是lint检测提示的作用之所在。
那么如何保证你调用的新的api的代码的相关类只会在合适的版本下才加载? 在这种情况下你可以“标注”目标的代码的所在版本的API。简单的注释代码@TargetApi(11)

If the whole class is targeting newer APIs, you can place the annotation on the class instead:

如果整个类都是新的api的版本,你就可以把@Target标注移除掉。


综上,@Target的作用在于提示:使用高编译版本的代码,为了通用性兼容运行此代码的低版本平台。要求程序员做出区分对待的加载。如用内部类等方式区分加载

总结:

Target API的注解级别是class,所以在class运行时,是没有这个注解信息的。它的作用就是在代码中调用了比minSDK版本高,但是不高于编译sdk版本的方法时,不让系统出现黄色警告,但是不代表这样写就可以在低版本sdk上运行,该方法还是只能被高版本调用。就是
if(Build.VERSION.SDK_INT >= 11){
      // 使用api11 新加 api
}else{
}

该方法只能放在i中运行,放在else中运行一样会异常崩溃。

所以targetAPI的作用只是让高于minSDK版本的方法编译不报错。


比如你的androidmanifest设置了minsdkversion为8,那么你在代码中使用了高于api8的代码,就算你用的是4.4的sdk进行的代码编译,只要你没使用@TargetApi,很抱歉,运

行android lint直接就显示错误提示。这个时候我们该怎么办呢?就是在方法或类的开头写上@TargetApi(xx)。如果你下面的代码要在api13的情况下运行,那么xx处你就填写13。

不能填低了,填低了,还是报错。

这和@SuppressLint("NewApi")不一样。suppress只告诉lint,我这代码如果高于你的minsdkversion,那么请忽略编译错误。


最后强调一点:targetapi和你代码的运行环境没任何关系。意思就是说即使你写了@TargetApi(11)。不代表你的这个 方法就会被限制在android 3.0的设备上运行。

因此兼容性判断还是必不可少的。所以@targetapi最常用的情景代码如下:

@TargetApi(11)

public void reqFragmentManger(){

if(Build.Version.SDK_INIT >= Build.VersionCodes.HONEYCOMB) {

FragmentManager manager = getFragmentManager();

}

你可能感兴趣的:(@TargetAPI)