AndroidAnnotations框架详解

简介

在之前的开发中,你肯定用到了xUtilsButterKnife等依赖注入框架,你可以使用这些框架来简化你的代码,因为很多代码都是重复性的,对于老司机来说,你肯定不想浪费大量的时间在写一些重复性的东西,比如findViewById之类的代码,所以好的框架的使用对于快速开发来说是很有必要的,今天要聊得就是开源框架AndroidAnnotations,先看一下官方介绍:

AndroidAnnotations is an Open Source framework that speeds up Android development. It takes care of the plumbing, and lets you concentrate on what’s really important. By simplifying your code, it facilitates its maintenance.

Fast Android Development. Easy maintainance

我们来翻译一下:

AndroidAnnotations是一个能让你进行快速开发的开源框架,它让你关注真正重要的地方,它可以简化你的代码,并且有利于你后期的维护;

快速开发,简单可维护

这就是AndroidAnnotations, 一款让你用了就停不下来的快速开发易维护的开源框架,ok,下面就跟着我的脚步,一起来揭开它的神秘面纱…

特点及环境配置

在官方首页中,给出了一个例子,使用前和使用后的对比,我们会发现代码减少了一半,可见其的强大,给出首页地址:点我,当然既然是开源的,也少不了GitHub项目地址:点我

使用这个框架的特点:

  1. 依赖注入(Dependency injection):支持view, extras, system service, resource等等
  2. 简单的线程模型(Simplified threading model):进行方法注解以让该方法在UI线程或后台线程进行执行
  3. 事件绑定(Event binding):进行方法注解以让方法执行view的时间而不用再添加一些监听
  4. REST client:创建一个接口,AndroidAnnotations用来实现
  5. 没有神秘感(No magic):AndroidAnnotations在编译时会产生一个子类,你可以查看子类中的代码来知道它是如何工作的.
  6. 编译检测:提供的多种注解,用于检测代码编译时可能存在的异常,并给开发者相关提示,提高代码质量
  7. AndroidAnnotations来实现这些美好的功能,只需要不到150kb的大小

环境配置

在AndroidStudio中,你只需在build.gradle中加入一行编译即可:

dependencies {
    compile ‘com.android.support:support-annotations:23.3.0’
}

当然,如果你的项目中已经使用了V7包,就可以直接使用了,是不是很简单…

使用

@Nullable 和 @NonNull

检测参数或者方法返回值是否可以为null,这是该框架中最常用也是最基础的注解之一了,使用了这两个注解,在Android Studio中,如果出现代码不安全的情况下,会给出智能提示,我们下面进行示例对比:

使用@NonNull注解修饰的参数不能为null,在下面的例子,我们有一个弹出name的函数,该函数需要保证传入的参数不能为null,我们来看一下对比:

未加注解:

加上@NoNull注解

我们可以看到加上的@NonNull注解后,Android Studio会自动检测不安全的代码并给出友好提示,提示开发者进行修改;当然如果我们改成@Nullable就不会出现提示了;

我们也可以将@Nullable作用在方法上,这样方法的返回值是允许为null的,但是可能会导致某些情况下的crash;

@CheckResult

该注解是为了检测方法返回值是否是需要使用的,如果没有被使用,则AndroidStudio会给出警告提示,下面进行示例对比:

未加注解:

加上@CheckResult注解

@EActivity、@ViewById、@Click

这三个注解应该是对我们的代码简洁性最有帮助的

  • @EActivity : 后面需要跟上一个layout id,来标示该Activity所加载的xml布局,这样原来的onCreate()方法就不用写了;
  • @ViewById : 与findViewById作用一致,而且@ViewById后面可以不写控件id,前提是控件变量名要与控件id一致
  • @Click : 也就是控件的点击事件,而且如果控件ID与方法名一致,后面就不用写控件ID了. 该注解可以单独写,也可以对多个Button合并写

我们现在写一个Activity是如何使用AndroidAnnotation框架的

import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

import com.googlecode.androidannotations.annotations.Click;
import com.googlecode.androidannotations.annotations.EActivity;
import com.googlecode.androidannotations.annotations.ViewById;

//这里加注解就可以不写onCreate方法
@EActivity(R.layout.activity_test_annotation)
public class TestAnnotation extends AppCompatActivity {

    @ViewById(R.id.tv_name)//如果变量名和控件ID一致,后面就不用写id
    TextView tv_name;

    @Click(R.id.showName)//如果控件ID与方法名一致,后面就不用写id
    public void showName(){
        Toast.makeText(this,tv_name.getText(),Toast.LENGTH_SHORT).show();
    }
}

我们来看如果有多个Button的点击事件该怎么写

@Click({R.id.bt1,R.id.bt2,R.id.bt3})  
void buttonClicked(Button bt){  
    switch(bt.getId()){  
    case R.id.bt1:  
        break;  
        ...  
    }  
}  

注意:如果控件ID与变量名一致,在@ViewById后没有写控件ID, 则在使用时就不能直接在showName方法中调用,因为在运行时会报一个空指针,所以需要在AfterView注解的方法中进行使用

@AfterView  
void init(){  
    tv_name.setText("Hello");  
}

资源引用类型注解

在我们平时开发中我们肯定会经常用到引用一些资源,比如图片资源及字符串资源或者颜色值资源,因为这些资源的类型都是int值,所以有时候我们在给TextView设置字符串资源时也有可能引用了图片资源ID,就会导致有问题,比如会出现以下异常:

android.content.res.Resources$NotFoundException: String resource ID #0x3039

而在代码检测的时候我们自己却很难发现,现在有了资源类型注解,这些问题都不再是问题了,我们先看一下资源类型注解主要都有哪些:

  • @StringRes : 表示参数、变量或者函数返回值应该是一个字符串类型的资源

  • @ColorInt : 表示参数、变量或者函数返回值应该是一个颜色值而不是颜色资源引用,例如应该是一个 AARRGGBB 的整数值。

  • @ColorRes : 表示参数、变量或者函数返回值应该是一个 color 类型的资源,而不是颜色值。注意和 ColorInt 区别

  • @AnimRes : 表示参数、变量或者函数返回值应该是一个 Anim 类型的资源

  • @DrawableRes : 表示参数、变量或者函数返回值应该是一个 drawable 类型的资源

  • @DimenRes : 表示参数、变量或者函数返回值应该是一个 dimension 类型的资源

我们下面进行代码示例对比,我们这里定义了一个方法,方法中只接受@StringRes注解的int引用

未加注解前:

加了注解后:

如果我们改为 R.string.app_name, 提示就会自动消失:

我们可以看到,AndroidStudio已经给了我们提示,这样我们再也不怕引用错误了;

线程注解

线程注解主要是用于检测一个函数是否在指定类型的线程中执行,有四种注解类型;

  • @UiThread

  • @MainThread

  • @WorkerThread

  • @BinderThread

其中@UiThread 和 @MainThread 在大部分的使用场景中,是可以替换使用的,如果一个类中的所有方法都在同一个线程中执行,就直接可以在类本身进行注解;

对于代码示例,已AsyncTask最为合适不过,我们都知道doInBackground方法为WorkThread,不可以进行UI更新,所以如果在onProgressUpdate方法外进行UI更新的话,IDE就会给我们直接的提示:

值约束注解 @FloatRange,@IntRange, @Size

@FloatRange 用法

如果在定义的方法中,需要传的参数是一个Float或者Double类型,而且又需要保证值在一定范围内,就可以使用 @FloatRange 注解,如图所示,如果设置范围为0.0~1.0,如果传值为12,IDE就会直接给出提示:

@IntRange用法

当然,你也可以对int值进行约束限定,比如限定为0~255,如果传值300,就会报出错误提示:

这些都是非常有用的,因为有的API限制传值为0~1,有的为0~255,有了这个注解限制,就不用怕在代码中传入了错误的参数;

@Size用法

对于数据,集合及字符串我们可以用@Size进行限制,用法如下:

  • 字符串最常为10: @Size(max=10)

  • 数组只能有2个元素: @Size(2)

  • 集合不能为空,至少有一个元素: @Size(min=1)

权限注解: @RequiresPermission

如果我们的方法需要某些权限,但是又不知道在清单文件中是否配置了,我们就可以使用这个权限注解;

方法所需权限注解

 @RequiresPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    public void writeInfo(String name){
        //TODO what you want
    }

如果需要多个权限的一个,使用 anyOf 属性:

@RequiresPermission(anyOf={Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}) 
public void writeInfo(String name){
//TODO what you want
}

如果需要使用多个权限,使用 allOf 属性:

@RequiresPermission(allOf = {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE}) 
public void writeInfo(String name){
//TODO what you want
}

intent权限注解

如果是intent的权限,我们可以在定义的intent常量上标注权限需求:

@RequiresPermission(Manifest.permission.BLUETOOTH)
    public static final String ACTION_VIEW = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";

Content Provider 权限注解

对于content providers的权限,可以用@Read或者@Write标注每一个权限需求:

@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
@RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");

Keep权限注解

相信我们每个打包的小伙伴都知道,如果想keep某个类里面的某个方法是一件多么痛苦的事情,你曾经在Proguard用到过类似这样的代码:

-keep class com.foo.bar { public static }

使用注解就会很方便的接军这些问题,AndroidAnnotations将会告诉Proguard不要对指定的函数或者类进行优化操作:

@Keep
public void setAnni(@IntRange(from=0, to=255) int anni){
    //TODO what you want
}

注意: 根据官方文档,目前该注解并没有加入到Gradle插件中,我们就继续等待吧…

好了,到此我们对于AndroidAnnotatios开源框架有了一定的了解,下面就尽情的去使用吧,这些只是框架中的一部分,更多好玩儿有趣的功能等待我们自己去发掘,希望大家都有美好的一天,生活不易,我们要好好珍惜…


版权声明:本文为SmallCheric原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。