怎样用 Android Annotations 写出高性能代码
2015-11-09 17:49
363 查看
上一篇博文中简单介绍了 Android Annotations 的基本用法,顺便扯了一下概念 - 契约编程,阅读量少的可怜,看来并没有多少人对此感兴趣,今天再来一篇,介绍几个稍微高级点的用法,我就不信弄不出一个大新闻。
本篇将要介绍的几个也许并不常用,但是逼格是有保证的,它们是
Thread Annotations
CheckResult Annotations
CallSuper Annotations
Enumerated Annotations
Thread Annotations 有四位成员 -
java 文件,却拥有着共同的 target,不信你看:
@Retention(CLASS)
@Target({METHOD,CONSTRUCTOR,TYPE})
如果标记 class,那么这个 class 的所有方法都必须在指定线程上执行,例如
@UiThread
public class NavigationBar {
@NonNull
private NavigationBar addEntry(
@StringRes int iconFontRes,
@NonNull String title,
@NonNull OnClickListener listener) {
// ...
}
// ...
}
这样一来,NavigationBar 的所有方法都要运行在 Ui Thread,否则 Android Studio 会!报!错!
- Support Annotations。总结起来一句话:
View Hierarchy,但是 Android Studio 认为两者是可以互换的,所以有这两种标记的方法可以互相调用。
然后我再稍微补充几句:
一个进程有且只有一个主线程 - @MainThread,同时它也是一个 @UiThread。例如,activity 的 main window 就运行在 @MainThread 上,但是系统也允许应用创建其他的线程以运行不同的 window(除了系统进程会这么干,几乎没有其他场景)
这个 Annotation 对于【只看方法名无法判断是否有返回值】的方法特别管用,例如:
public
boolean
openUp()
只看方法名
但是如果必须要判断
![](http://img.blog.csdn.net/20151023161711372)
如果你提供了 api 给别人用,但是这个 api 必须要先调用父类方法才能正确执行,怎么办?让
![](http://img.blog.csdn.net/20151023162712250)
编写高性能代码,从不用 enum 开始!
每一个 enum 都是一个对象,无论从内存还是从性能上来看,都没有一个 primitive type 的变量效率高。
例如,定义一个类 -
enum,可能会写成下面这样:
public class ActionBar {
public enum Theme {
DARK, LIGHT
}
private Theme mTheme;
public void setTheme(Theme theme) {
mTheme = theme;
}
}
为了提升代码效率,可以用两个整形变量来替代
public class ActionBar {
public static final int DARK = 0x00;
public static final int LIGHT = 0x01;
private int mTheme;
public void setTheme(int theme) {
mTheme = theme;
}
}
如何既能提升效率又可以保证传入参数的合法性呢?
用
public class ActionBar {
@IntDef({DARK, LIGHT})
@Retention(RetentionPolicy.SOURCE)
public @interface Theme {}
public static final int DARK = 0x00;
public static final int LIGHT = 0x01;
private int mTheme;
public void setTheme(@Theme int theme) {
mTheme = theme;
}
@Theme
public int getTheme() {
return mTheme;
}
}
如果用户调用 setTheme 时传入了非法参数,Android Studio 会!报!错!
![](http://img.blog.csdn.net/20151023170201901)
如果我们打算把
flag,允许用户通过逻辑运算去自由组合,也就说可以这样调用
setTheme(DARK | LIGHT);
setTheme(DARK & LIGHT);
只需要把
String 类型。
http://anupcowkur.com/posts/a-look-at-android-support-annotations/
http://developer.android.com/tools/debugging/annotations.html
版权声明:本文为博主原创文章,未经博主允许不得转载。
本篇将要介绍的几个也许并不常用,但是逼格是有保证的,它们是
Thread Annotations
CheckResult Annotations
CallSuper Annotations
Enumerated Annotations
Thread Annotations
Thread Annotations 有四位成员 - @UiThread、
@MainThread、
@WorkerThread、
@BinderThread,它们来自不同的
java 文件,却拥有着共同的 target,不信你看:
@Retention(CLASS)
@Target({METHOD,CONSTRUCTOR,TYPE})
如果标记 class,那么这个 class 的所有方法都必须在指定线程上执行,例如
@UiThread
public class NavigationBar {
@NonNull
private NavigationBar addEntry(
@StringRes int iconFontRes,
@NonNull String title,
@NonNull OnClickListener listener) {
// ...
}
// ...
}
这样一来,NavigationBar 的所有方法都要运行在 Ui Thread,否则 Android Studio 会!报!错!
@MainThread与
@UiThread的区别比较微妙,首先放放链接
- Support Annotations。总结起来一句话:
@MainThread用于标记与生命周期相关的方法,
@UiThread用于
View Hierarchy,但是 Android Studio 认为两者是可以互换的,所以有这两种标记的方法可以互相调用。
然后我再稍微补充几句:
一个进程有且只有一个主线程 - @MainThread,同时它也是一个 @UiThread。例如,activity 的 main window 就运行在 @MainThread 上,但是系统也允许应用创建其他的线程以运行不同的 window(除了系统进程会这么干,几乎没有其他场景)
@CheckResult
这个 Annotation 对于【只看方法名无法判断是否有返回值】的方法特别管用,例如:public
boolean
openUp()
只看方法名
openUp,可能不会多想,调用一下就完事了,也不会判断返回值。
但是如果必须要判断
openUp的返回值,除了文档约束好像也没有其他办法,有了
@CheckResults,一切都变得简单明了。
@CallSuper
如果你提供了 api 给别人用,但是这个 api 必须要先调用父类方法才能正确执行,怎么办?让 @CallSuper来拯救你。
Enumerated Annotations
编写高性能代码,从不用 enum 开始!每一个 enum 都是一个对象,无论从内存还是从性能上来看,都没有一个 primitive type 的变量效率高。
例如,定义一个类 -
ActionBar,用户可以通过
setMode设置不同的模式,如果使用
enum,可能会写成下面这样:
public class ActionBar {
public enum Theme {
DARK, LIGHT
}
private Theme mTheme;
public void setTheme(Theme theme) {
mTheme = theme;
}
}
为了提升代码效率,可以用两个整形变量来替代
Theme,但是这样无法保证参数
theme的合法性,用户可能传入了
DARK和
LIGHT之外的值。
public class ActionBar {
public static final int DARK = 0x00;
public static final int LIGHT = 0x01;
private int mTheme;
public void setTheme(int theme) {
mTheme = theme;
}
}
如何既能提升效率又可以保证传入参数的合法性呢?
用
@IntDef来添加一个约束就搞定了。
public class ActionBar {
@IntDef({DARK, LIGHT})
@Retention(RetentionPolicy.SOURCE)
public @interface Theme {}
public static final int DARK = 0x00;
public static final int LIGHT = 0x01;
private int mTheme;
public void setTheme(@Theme int theme) {
mTheme = theme;
}
@Theme
public int getTheme() {
return mTheme;
}
}
如果用户调用 setTheme 时传入了非法参数,Android Studio 会!报!错!
如果我们打算把
DARK和
LIGHT作为一个
flag,允许用户通过逻辑运算去自由组合,也就说可以这样调用
setTheme。
setTheme(DARK | LIGHT);
setTheme(DARK & LIGHT);
只需要把
@IntDef的
flag属性设为
true即可。
public class ActionBar { @IntDef(flag = true, value = {DARK, LIGHT}) @Retention(RetentionPolicy.SOURCE) public @interface Theme {} public static final int DARK = 0x00; public static final int LIGHT = 0x01; private int mTheme; public void setTheme(@Theme int theme) { mTheme = theme; } @Theme public int getTheme() { return mTheme; } }
@StringDef与
@IntDef的原理一样,只不过用到的常量是
String 类型。
参考资料
http://anupcowkur.com/posts/a-look-at-android-support-annotations/http://developer.android.com/tools/debugging/annotations.html
版权声明:本文为博主原创文章,未经博主允许不得转载。
相关文章推荐
- Android自定义控件之仿美团下拉刷新
- 监听android home键的实现方式
- Android Intent.FLAG_NEW_TASK详解,包括其他的标记的一些解释
- Android自定义控件之仿汽车之家下拉刷新
- cordova android项目自定义插件及使用(一)
- Android应用程序打包时,出现错误:"XXX" is not translated in "af" (Afrikaans), "am" (Amharic), "ar" (Arabic).....
- Android中的Parcel机制 实现Bundle传递对象
- android 异常 :ScrollView can host only one direct child
- Android-Android5.1屏幕固定功能(screen pinning)分析
- MAC OS 下使用Android Studio获取开发版和发布版SHA1证书
- Android 内存分析
- Android Volley框架的使用(三)
- 解决Android开发中,ActiveAndroid和Gson同时使用,对象序列化失败的问题
- 《ArcGIS Runtime SDK for Android开发笔记》——数据制作篇:紧凑型切片制作(Server缓存切片)
- android wear 真机截图
- Android——支付宝SDK调用(移动应用接入支付宝支付,提供安全、便捷的支付能力)
- Android Volley框架的使用(二)
- android中getMeasureWidth()和getWidth()方法的区别
- Android Sensor感应器介绍(三)获取用户移动方向,指南针原理
- android——EventBus(一)