AndroidStudio中使用AndroidAnnotation的简单介绍

简介

1、配置环境变量

1、在project的build.gradle中添加如下代码:

dependencies {
    -------
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4+'
}

2、在app的build.gradle中添加如下代码:

apply plugin: 'com.android.application'
//annotations注解
apply plugin: 'android-apt'
def AAVersion = '3.3.2'
---
// 注解框架
apt {
    arguments {
        androidManifestFile variant.outputs[0].processResources.manifestFile
        resourcePackageName '程序的包名'
    }
}
dependencies {
    ---
    //annotations註解
    apt "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
}

2、示例代码

示例代码1

@EActivity(R.layout.translate) // Sets content view to R.layout.translate
public class TranslateActivity extends Activity {

    @ViewById // Injects R.id.textInput 
    EditText textInput;  // 使用注解变量不能被private修饰 

    @ViewById(R.id.myTextView) // Injects R.id.myTextView
    TextView result;

    @AnimationRes // Injects android.R.anim.fade_in
    Animation fadeIn;

    @StringRes(R.string.hello) // 检索String资源文件
    String myHelloString;
    
    @StringRes
    String hello;

    @ColorRes(R.color.backgroundColor) // 检索Color资源文件
    int someColor;

    @ColorRes
    int backgroundColor;

    @DimensionRes(R.dimen.fontsize) // 检索dimension 资源
    float fontSizeDimension;

    @DimensionRes
    float fontsize;

    // @DimensionPixelOffsetRes 注解用来检索dimension 资源。
    // 获得一个以整型的像素偏移量为最终值的dimension 。这个注解功能和@DimensionRes一样,除了原始浮点数被截断成一个整型(像素)值。
    @DimensionPixelOffsetRes(R.string.fontsize)
    int fontSizeDimension;

    @DimensionPixelOffsetRes
    int fontsize;

    // @DimensionPixelSizeRes注解用来检索dimension 资源。
    //获得一个以整型的像素大小为最终值的dimension 。
    //这个注解功能和@DimensionRes一样,除了原始浮点数被截断成一个整型(像素)值作为大小值。
    //大小转换涉及到基值舍入,确保一个非零的基值至少有1像素的大小。

    @DimensionPixelSizeRes(R.string.fontsize)
    int fontSizeDimension;

    @DimensionPixelSizeRes
    int fontsize;

    @Click // When R.id.doTranslate button is clicked 按钮的点击事件
    void doTranslate() {
         translateInBackground(textInput.getText().toString());
    }

    @Background // Executed in a background thread 后台线程中执行的代码
    void translateInBackground(String textToTranslate) {
         String translatedText = callGoogleTranslate(textToTranslate);
         showResult(translatedText);
    }
   
    @UiThread // Executed in the ui thread 主线程中执行的代码
    void showResult(String translatedText) {
         result.setText(translatedText);
         result.startAnimation(fadeIn);
    }

    // [...]
}

示例代码2

//Eactivity注释可以设置Layout,相当于setConentView方法
@EActivity(R.layout.activity_main)
@Fullscreen // 全屏
@NoTitle
public class MainActivity extends Activity {
    //ViewById注释功能与findViewById相同,如果声明的变量名就是id,可以省去参数,否则应加上id,如ViewById(R.id.tv)
    
    @ViewById
    TextView tv;
    @ViewById
    EditText edit;
    @StringRes(R.string.hello_world)
    String hello;
    //需要使用@Bean标签
    @Bean
    Student stu;
    //AfterViews注释定义的方法会在OnCreate方法的setContentView后执行
    @AfterViews
    void init()
    {
        tv.setText("asfsdf");
    }
    //在EditText内容改变时,更新TextView内容
    @AfterTextChange(R.id.edit)
    void afterEditChange(Editable text, TextView hello)
    {
        tv.setText(hello.getText());
    }
    //点击TextView时调用
    @Click(R.id.tv)
    void tvClicked()
    {
        stu.Toast();
        stu.backThread();
    }
    //在stu中也可以回调这个方法来更新UI
    @UiThread
    public void updateTv(int i)
    {
        tv.setText(String.valueOf(i));
    }
 
    
}

Enhancing custom classes 优化自定义类

你可以在一个不是标准Android组件(比如Activity,Service)的类中使用注解。
你只需要使用 @EBean进行注解:

@EBean
public class MyClass {

}

一个用 @EBean 注解的类必须只有一个构造函数。这个构造函数必须是无参的,或者,在AndroidAnnotations 2.7以后,可以带一个类型为Context的参数。

Injecting implementations in assignable fields 注入实现到指定的字段

假如你想在代码中通过API使用一个依赖关系(不论是父类还是接口),你可以指定实现类作为 @Bean 注入的参数值。

@EActivity
public class MyActivity extends Activity {

    /* 
     * A MyImplementation instance will be injected.      
     * MyImplementation must be annotated with @EBean and implement MyInterface.     
     */
    @Bean(MyImplementation.class)
    MyInterface myInterface;

}

那样是不是提供了松耦合的优势呢?其实,这个类还是知道它自己的依赖实现,但是至少代码使用这些依赖必须依靠API,这其实是一个很有意思的目的。

Supported annotations 所支持的注解

你可以在 @EBean 类中使用大部分的AA注解:

@EBean
public class MyClass {

  @SystemService
  NotificationManager notificationManager;

  @UiThread
  void updateUI() {

  }

}

View related annotations 和视图相关的注解

你可以在 @EBean 类中使用和视图相关 (@View, @Click...) 的注解:

@EBean
public class MyClass {

  @ViewById
  TextView myTextView;

  @Click(R.id.myButton)
  void handleButtonClick() {

  }
}

请注意,只有当依赖于 MyClass 的Android根组件是一个activity,并且它的布局文件包含了所需的视图,这些注解才会生效。否则, myTextView 会为null,handleButtonClick() 也永远不会被调用。

Injecting the root context 注入root context

你可以使用@RootContext 注解注入依赖你 @EBean 类的Android根组件。请注意,只有当context的类型正确时,注入才会成功。

@EBean
public class MyClass {

  @RootContext
  Context context;

  // Only injected if the root context is an activity
  @RootContext
  Activity activity;

  // Only injected if the root context is a service
  @RootContext
  Service service;

  // Only injected if the root context is an instance of MyActivity
  @RootContext
  MyActivity myActivity;

}

在下面这个activity中有一个上述的 MyClass 实例,它的字段 service 将为空。

@EActivity
public class MyActivity extends Activity {

  @Bean
  MyClass myClass;

}

Executing code after dependency injection 在依赖注入后执行代码

当你的 @EBean 注解类的构造器被调用后,它的字段还没有注入进来。假如你需要在构建项目的时候执行代码,那么在依赖注入后,你需要添加使用@AfterInject 注解的方法。

@EBean
public class MyClass {

  @SystemService
  NotificationManager notificationManager;

  @Bean
  MyOtherClass dependency;

  public MyClass() {
    // notificationManager and dependency are null
  }

  @AfterInject
  public void doSomethingAfterInjection() {
    // notificationManager and dependency are set
  }

}

Scopes 作用域

Since AndroidAnnotations 2.5

AndroidAnnotations现在支持两个作用域:

  • 默认作用域:每次当新的bean实例创建时都需要注入一个bean

  • 单例作用域:只有第一次才创建bean实例。然后之后一直使用同一个实例注入。

      @EBean(scope = Scope.Singleton)
      public class MySingleton {
    
      }
    

Caution警告

  • 假如你的bean有了 Singleton 作用域,它将保持application context的引用(使用context.getApplicationContext()。那是因为它是生命周期比任何activity或者service都长,所以它应该在任何Android组件中保留引用,避免引起内存泄漏。

  • 同样,我们也在使用Singleton作用域的 @EBean 组件中禁用了视图注入和视图事件绑定(视图拥有activity的引用,因此有可能产生内存泄漏)。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容