一探究竟:安卓老牌注解框架androidannotations

版权声明:天际流火叩响大地之门,岁月星辰刻画沧桑年轮! https://blog.csdn.net/ytfunnysite/article/details/79959875

简介

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,下面就跟着我的脚步,一起来揭开它的神秘面纱…

直接上代码:

package com.rest.template.resttemplate.activities;

import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;

import com.rest.template.resttemplate.R;
import com.rest.template.resttemplate.client.RestClient;
import com.rest.template.resttemplate.client.facades.IpFacade;
import com.rest.template.resttemplate.client.facades.ResponseHeadersFacade;
import com.rest.template.resttemplate.client.listener.RestClientListener;
import com.rest.template.resttemplate.client.model.template.Ip;
import com.rest.template.resttemplate.client.model.template.ResponseTest;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;

/**
 *  这里加注解就可以不写onCreate()方法
 *  直接绑定xml布局文件
 */
@EActivity(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {

    private static final String TAG = "SplashScreenActivity";

    @Bean
    protected RestClient restClient;

    @Bean
    protected IpFacade ipFacade;

    @Bean
    protected ResponseHeadersFacade responseHeadersFacade;

    /**
     * 正常控件的注解模式,类似findviewbyid
     */
    @ViewById(R.id.id_button)
    Button  id_button;
    /**
     * 变量名与控件ID相同时,省略@ViewById后边的id
     */
    @ViewById
    Button response_test_button;

    /**
     * 多个控件的点击事件
     * 如果控件ID与变量名一致,在@ViewById后没有写控件ID, 则在使用时就不能直接在方法中调用,
     * 因为在运行时会报一个空指针,所以需要在AfterView注解的方法中进行使用
     * @param button
     */
    @Click({R.id.id_button,R.id.response_test_button})
    public void clicks(Button button){
        switch (button.getId()){
            case R.id.id_button:
                break;
            case R.id.response_test_button:
                break;
            default:
        }
    }

    @AfterViews
    protected void initGui() {
        restClient.cancelAll();
    }


    /**
     * 正常点击事件的注解方式
     */
    @Click(R.id.id_button)
    public void onIpClick() {
        ipFacade.getIp(new RestClientListener<Ip>() {
            @Override
            public void onSuccess(Ip ip) {
                onSuccessResult(ip);
            }

            @Override
            public void onFailed(Exception ex, String msg) {
                onFailedResult(ex, msg);
            }
        });
    }

    /**
     * 点击事件注解,控件ID与方法名一致,
     * 省略onClick()括号内控件ID
     */
    @Click
    public void response_test_button(){
        showDialog("控件ID与方法名一致,省略ID");
    }
//    @Click(R.id.response_test_button)
//    public void onResponseTestClick() {
//        responseHeadersFacade.getResponseHeaders("TEST", "TEST_VALUE", new RestClientListener<ResponseTest>() {
//            @Override
//            public void onSuccess(ResponseTest responseTest) {
//                onSuccessResult(responseTest);
//            }
//
//            @Override
//            public void onFailed(Exception ex, String msg) {
//                onFailedResult(ex, msg);
//            }
//        });
//    }


    private void onSuccessResult(Object object) {
        Log.e(TAG, object.toString());
        showDialog(object.toString());
    }

    private void onFailedResult(Exception ex, String msg) {
        if(ex != null) {
            Log.e(TAG, msg, ex);
        } else {
            Log.e(TAG, msg);
        }
    }

    @UiThread
    protected void showDialog(final String message) {
        new AlertDialog.Builder(MainActivity.this)
                .setTitle(getString(R.string.information))
                .setMessage(message)
                .show();
    }
}

PS:其他常用注解字段:

>

@StringRes : 表示参数、变量或者函数返回值应该是一个字符串类型的资源
@ColorInt : 表示参数、变量或者函数返回值应该是一个颜色值而不是颜色资源引用,例如应该是一个 AARRGGBB 的整数值。
@ColorRes : 表示参数、变量或者函数返回值应该是一个 color 类型的资源,而不是颜色值。注意和 ColorInt 区别
@AnimRes : 表示参数、变量或者函数返回值应该是一个 Anim 类型的资源
@DrawableRes : 表示参数、变量或者函数返回值应该是一个 drawable 类型的资源
@DimenRes : 表示参数、变量或者函数返回值应该是一个 dimension 类型的资源
@AfterInject 定义的方法在类的构造方法执行后执行
@AfterTextChange定义的方法在TextView及其子类的Text属性改变后执行
@AfterViews 定义的方法在setContentView后执行
@Background //开启新线程后台运行,注意不要引用UI控件,而且返回值类型一定是void
@UiThread 定义的方法在主线程执行
@UiThread(delay=2000) //可以设置延时时间,以毫秒为单位
@BeforeTextChange 定义的方法在TextView及其子类的Text属性改变前执行
@Click //事件控制,可以以按钮的id作为方法名,同时支持的事件还有onLongClick,onTextChange等
@EActivity //布局文件在这里声明,不用在setContentView
@EProvider 在 ContentProvider中启用Annotations
@EReceive 在BroadcastReceiver中启用Annotations
@EService 在Service中启用Annotations
@EView 在自定义的View的子类中启用Annotations
@Fullscreen 全屏
@NoTitle 无标题栏
@ViewById //控件这样标注,由于是IOC模式,因此不需要自己实例化
@ViewById(R.id.myTextView) //提供id来生成控件,如果不指定ID,默认以控件名进行查找,如上面的myEditText
@StringRes(R.string.hello) //String资源
@DimensionRes(R.dimen.activity_horizontal_margin)//dimen资源
@Extra(MainActivity.NAME_KEY) //取Intent传递的值
@WindowFeature({Window.FEATURE_NO_TITLE,Window.FEATURE_INDETERMINATE_PROGRESS})

线程注解

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

@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,就会报出错误提示
这里写图片描述

@Size用法

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

字符串最常为10: @Size(max=10)
![这里写图片描述](https://img-blog.csdn.net/20180416140301165?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l0ZnVubnlzaXRl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
数组只能有2个元素: @Size(2)
![这里写图片描述](https://img-blog.csdn.net/20180416140330485?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3l0ZnVubnlzaXRl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
集合不能为空,至少有一个元素: @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}) <br>  
        public void writeInfo(String name){ <br>  
            //TODO what you want <br>  
        }  

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

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

intent权限注解

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

Content Provider 权限注解

相信我们每个打包的小伙伴都知道,如果想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  
    }  

@RequiresPermissions 解释

参考文章:https://blog.csdn.net/chenzhen200638/article/details/56298918

@RequiresAuthentication
验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时。
@RequiresUser
验证用户是否被记忆,user有两种含义:
一种是成功登录的(subject.isAuthenticated() 结果为true);
另外一种是被记忆的(subject.isRemembered()结果为true)。
@RequiresGuest
验证是否是一个guest的请求,与@RequiresUser完全相反。
 换言之,RequiresUser  == !RequiresGuest。
此时subject.getPrincipal() 结果为null.
@RequiresRoles
例如:@RequiresRoles("aRoleName");
  void someMethod();
如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。
@RequiresPermissions
例如: @RequiresPermissions({"file:read", "write:aFile.txt"} )
  void someMethod();
要求subject中必须同时含有file:read和write:aFile.txt的权限才能执行方法someMethod()。否则抛出异常AuthorizationException。
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页