close
当前位置: 物联网在线 > 技术文库 > android >

探究 Android 中的注解

注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理.

归纳而言,Android中的注解大概有以下好处

提高我们的开发效率

更早的发现程序的问题或者错误

更好的增加代码的描述能力

更加利于我们的一些规范约束

提供解决问题的更优解

准备工作

默认情况下,Android中的注解包并没有包括在framework中,它独立成一个单独的包,通常我们需要引入这个包.

dependencies { compile 'com.android.support:support-annotations:22.2.0' }

但是如果我们已经引入了 appcompat 则没有必要再次引用 support-annotations ,因为 appcompat 默认包含了对其引用.

替代枚举

在最早的时候,当我们想要做一些值得限定实现枚举的效果,通常是

定义几个常量用于限定

从上面的常量选取值进行使用

一个比较描述上面问题的示例代码如下

public static final int COLOR_RED = 0; public static final int COLOR_GREEN = 1; public static final int COLOR_YELLOW = 2; public void setColor(int color) { //some code here } //调用 setColor(COLOR_RED)

然而上面的还是有不尽完美的地方

setColor(COLOR_RED) 与 setColor(0) 效果一样,而后者可读性很差,但却可以正常运行

setColor方法可以接受枚举之外的值,比如 setColor(3) ,这种情况下程序可能出问题

一个相对较优的解决方法就是使用Java中的Enum.使用枚举实现的效果如下

// ColorEnum.java public enum ColorEmun { RED, GREEN, YELLOW } public void setColorEnum(ColorEmun colorEnum) { //some code here } setColorEnum(ColorEmun.GREEN);

然而Enum也并非最佳,Enum因为其相比方案一的常量来说,占用内存相对大很多而受到曾经被Google列为不建议使用,为此Google特意引入了一些相关的注解来替代枚举.

Android中新引入的替代枚举的注解有 IntDef 和 StringDef ,这里以 IntDef 做例子说明一下.

public class Colors { @IntDef({RED, GREEN, YELLOW}) @Retention(RetentionPolicy.SOURCE) public @interface LightColors{} public static final int RED = 0; public static final int GREEN = 1; public static final int YELLOW = 2; }

声明必要的int常量

声明一个注解为LightColors

使用@IntDef修饰LightColors,参数设置为待枚举的集合

使用@Retention(RetentionPolicy.SOURCE)指定注解仅存在与源码中,不加入到class文件中

Null相关的注解

和Null相关的注解有两个

@Nullable 注解的元素可以是Null @NonNull 注解的元素不能是Null

上面的两个可以修饰如下的元素

成员属性

方法参数

方法的返回值

@Nullable private String obtainReferrerFromIntent(@NonNull Intent intent) { return intent.getStringExtra("apps_referrer"); }

NonNull检测生效的条件

显式传入null

在调用方法之前已经判断了参数为null时

setReferrer(null);//提示警告 //不提示警告 String referrer = getIntent().getStringExtra("apps_referrer"); setReferrer(referrer); //提示警告 String referrer = getIntent().getStringExtra("apps_referrer"); if (referrer == null) { setReferrer(referrer); } private void setReferrer(@NonNull String referrer) { //some code here } 区间范围注解

Android中的IntRange和FloatRange是两个用来限定区间范围的注解,

float currentProgress; public void setCurrentProgress(@FloatRange(from=0.0f, to=1.0f) float progress) { currentProgress = progress; }

如果我们传入非法的值,如下所示

setCurrentProgress(11);

就会得到这样的错误

Value must be >=0.0 and <= 1.0(was 11) 长度以及数组大小限制

限制字符串的长度

private void setKey(@Size(6) String key) { }

限定数组集合的大小

private void setData(@Size(max = 1) String[] data) { } setData(new String[]{"b", "a"});//error occurs

限定特殊的数组长度,比如3的倍数

private void setItemData(@Size(multiple = 3) String[] data) { } 权限相关

在Android中,有很多场景都需要使用权限,无论是Marshmallow之前还是之后的动态权限管理.都需要在manifest中进行声明,如果忘记了,则会导致程序崩溃. 好在有一个注解能辅助我们避免这个问题.使用RequiresPermission注解即可.

@RequiresPermission(Manifest.permission.SET_WALLPAPER) public void changeWallpaper(Bitmap bitmap) throws IOException { } 资源注解

在Android中几乎所有的资源都可以有对应的资源id.比如获取定义的字符串,我们可以通过下面的方法

public String getStringById(int stringResId) { return getResources().getString(stringResId); }

使用这个方法,我们可以很容易的获取到定义的字符串,但是这样的写法也存在着风险.

getStringById(R.mipmap.ic_launcher)
(责任编辑:ioter)

用户喜欢...

Android Weekly #276 安卓开发周刊 中文版

您是否了解过Android的Lifecycle-Aware库?(android.jlelse.eu) 我们如何了解Lifecycle-Aware库代码? Nishant Srivastava展示了可以跟踪活动或Lifecycle-Aware的Lifecycle Arch组件的片段,并相应地调整其行为。 为Mos...


Android Weekly #275 安卓开发周刊 中文版

MapMe — Android地图适配器 (medium.com) Josh Burton介绍MapMe,是一个用Kotlin编写的Android库,可以将适配器模式带到地图上。 赞助 CloudRail - 连接到API 10x更快 (cloudrail.com) 当我们用单一的界面连接到所...


使用Android Studio开发可独立运行(runnable)混淆过的Jar程序

之前开发Java程序一直都是使用Eclipse 开发Jar程序,现在开发基本上都已经弃用Eclipse了,但是有时偶尔开发个小的Jar程序,还要切换回去好麻烦,刚好前几天有人问几个相关的问题,就顺便整...


Android Weekly #274 安卓开发周刊 中文版

探索Android Oreo上的别后执行限制(medium.com) 在这篇文章中,Joe Birch解释了关于Android Oreo在后台运行服务的变化。 non-Time领主的time – 第5部分 (blog.stylingandroid.com) Mark Allison继续分析JSR 310 date和...


Android Weekly #273 安卓开发周刊 中文版

开源你的Android代码(android.jlelse.eu) 通过您的开源Android代码,您将(希望地)为Android社区提供有价值的代码,收到建设性的反馈,并与您最初建立的内容进行协作从而使您的代码变得更好。这...


Android Weekly #272 安卓开发周刊 中文版

Android Dev 101:每个初学者都应该知道的一些做法() 看一些初学者或媒介等级开发人员(不要错过任何人)应该知道的一些做法,以便更好地摆脱Android框架。 99.9% crash free sessions (medium.com) Chr...


Android Weekly #271 安卓开发周刊 中文版

依赖注入检查(medium.com) 在本文中,MihályNagy引入了依赖注入检查,一种开源注释处理器,可帮助您解决一些出现在所有JSR 330 DI库中常见的问题。 使用Android Studio插件提高效率 (blog.mindorks.com...


Android Weekly #270 安卓开发周刊 中文版

带有RxJava2的SOLID Android分析 (medium.com) 在这篇文章中,Aris Papadopoulos将解释如何正确创建一个分析系统,同时遵循SOLID原则,并使用RxJava2来解决问题。 (blog.stylingandroid.com) Java中的编程时间很难...


Android内存泄漏思考

Android内存泄漏是一个经常要遇到的问题,程序在内存泄漏的时候很容易导致OOM的发生。那么如何查找内存泄漏和避免内存泄漏就是需要知晓的一个问题,首先我们需要知道一些基础知识。...


Android Weekly #269 安卓开发周刊 中文版

在Google上快速提出操作 () Wolfram Rittmeyer分享了开始在Google上快速创建操作所需的所有信息(为了家庭与助理)。 RxJava中的错误处理(rongi.github.io) 一旦开始编写RxJava代码,你就会意识到有些事...