AndroidAnnotations配置使用

说明

AndroidAnnotations(以下简称AA)是一个能让你专注于更快速的开发Android 应用的开源框架,当你的项目中引入对他的使用能够让你的代码看起来更加的简洁,更加有利于代码的可阅读性,使你的项目更加容易维护。
这里奉上项目地址 AndroidAnnotations Github。

特性

  1. 依赖注入:inject views, extras, system services, resources, …
  2. 简化线程模型:通过注释的方式指定当前的方法要执行在什么线程,抛弃繁琐的AsyncTask,Thread等书写方式
  3. 事件绑定:通过使用注释的方式来处理点击事件@Click,文本内容改变监听@TextChange,@OnLongClick长按事件、等等…抛弃了传统的setonclicklistener等的复杂写法
  4. REST客户端:创建一个网络连接客户端接口
  5. No magic:官方文档中给出了这样一个词语来描述这其中的一个特性”没有魔法”,起初阅读时我并不能理解他想说的,当我详细查看他实现的原理的时候,我想我或许明白他所说的No magic是什么意思了,即他与别的框架不同的是,AA是在编译时生成当前注释类的直接final子类代码,而非运行时利用反射的方式处理事件。java的反射是神奇的,Magic的,它可以让你将对方隐藏起来的方法属性拿到手(当然你拿到手做什么就是你的需求了),但随之而来的是性能的降低,相比于利用反射,AA的编译时生成代码就是No Magic的。

配置

Eclipse

在Eclipse中使用AA你可能需要下载以下俩个Jar文件 [ androidannotations-api ],[ androidannotations ]

  1. 首先将androidannotations-api.jar放入libs目录中
  2. 在Eclipse项目中新建一个与libs目录平级的compile-libs文件夹,将androidannotations.jar包拷贝到该文件夹中
  3. 右击项目选中Properties选项
  4. 在Java Compiler选项下的Annotations Processin项中的第一项勾上
    AndroidAnnotations配置使用_第1张图片
  5. 将Factory Path项的第一项勾上,并且点击Add JARs按钮
    AndroidAnnotations配置使用_第2张图片
  6. 找到该项目之前创建的compile-libs文件中添加的jar包,OK
    AndroidAnnotations配置使用_第3张图片
  7. Eclipse下配置完成

AndroidStudio

项目Build.gradle中添加如下依赖

dependencies {
    compile fileTree(include: ['*.jar', '*.arr'], dir: 'libs')
    compile 'org.androidannotations:androidannotations:4.1.0'
}

**当然你也可以选择官方的添加方式

apply plugin: 'com.android.application'

//step 1
//添加依赖插件,定义版本号
apply plugin: 'android-apt'
def AAVersion = '4.1.0'

//step 2
buildscript {
    //指定远程仓库
    repositories {
        mavenCentral()
    }
    //依赖库
    dependencies {
        // 记得保持版本号与您根目录下 build.gradle 中所依赖的版本号一致
        classpath 'com.android.tools.build:gradle:2.2.+'
        // 保持最新的版本号,当前是1.8
        // 最新版查看地址-http://mvnrepository.com/artifact/com.neenbedankt.gradle.plugins/android-apt
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

//step 3
apt {
    arguments {
        androidManifestFile variant.outputs[0]?.processResources?.manifestFile
    }
}

// step 4
dependencies {
    // ......
    // 具体的依赖
    apt "org.androidannotations:androidannotations:$AAVersion"
    compile "org.androidannotations:androidannotations-api:$AAVersion"
}

android {
    //.......
}

Talk is cheap. Show me the code.


@EActivity(R.layout.activity_main)
@Fullscreen                         //全屏
@WindowFeature(Window.FEATURE_NO_TITLE)
//Fragment:@EFragment
//类:@EBean
public class MainActivity extends Activity {
    @App
    BaseApplication app;
     //代替findViewById(当你的名称相同的时候可以不用写(R.id.button) )
     @ViewById
     TextView tvAmText;
     @ViewById(R.id.button)
     Button mButton;
     @ViewsById({R.id.tv_asa_model,R.id.tv_asa_sn})//一次引入多个
     TextView tvAsaModel,tvAsaSn;

    //引入 String 资源,id 的使用同上
    @StringRes
    String spinner_dept_tips;

    //以下资源的引用同上
    /**
    * @AnimationRes
    * @BooleanRes
    * @ColorRes
    * @ColorStateListRes
    * @DimensionRes
    * @DrawableRes
    * @HtmlRes
    * @IntArrayRes
    * @IntegerRes
    * @LayoutRes
    * @MovieRes
    * @StringArrayRes
    * @StringRes
    * @TextArrayRes
    * @TextRes
    */
    /**
    * Intent intent=getIntent();
    * String asset_id = intent.getStringExtra("asset_id");
    */
    @Extra("asset_id"
    String asset_id;

    //取代原来的clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
    @SystemService
    ClipboardManager mCBManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //MainActivity 的 onCreate() 方法中不要执行任何与 layout 控件相关的操作
    }

    /**
     * 初始化控件
     * 在初始化控件的时候一定要注意加上@AfterViews注解
    否则可能会报空指针异常
     */
    @AfterViews
    void initView() {
        tvAmText.setText("开始学习注解的使用");
    }

    //点击事件,同理,长按:@LongClick,触摸:@Touch
    /**
    * @LongClick 长按触摸
    * @Touch     触摸
    * @ItemClick 条目点击事件
    */
    @Click(R.id.button)
    void btClick() {
        Toast.makeText(MainActivity.this, "start", Toast.LENGTH_SHORT).show();
        doInBack();
    }


    /**
     * 
     */
    @Background
    void doInBack() {
        //当前方法执行线程为子线程
    }

    @UiThread
    /**
     * 在子线程中更新 UI 线程
     */
    void doInUiThread() {
        //当前方法执行在主线程
    }
    private final static int REQUEST_CODE=0x1001
    @OnActivityResult(REQUEST_CODE)
    void onResult(int resultCode) {
    }
}

优点:

  • 提高了开发的效率
  • 代码看起来更加整洁
  • 方便统一管理
  • 提高了代码的复用性
  • 代码的可阅读性大大提高
  • 编译时注解,避免使用反射带来的性能影响
  • 更快速的线程切换

缺点:

  • 出错抛异常的时候难以看懂(因为他会抛出很多无关的错误信息),难以定位。

    • 问题排查
      • 首先检测你使用了EActivity的Activity在注册时是否使用了下划线结尾
      • 查看异常信息的最后几行,往往是问题的关键,前边抛出的问题基本上都是由于最后几行的异常产生的衍生问题,当你解决了最后边的异常信息重新编译基本就OK了
      • 这里记录一个问题’com.android.support.test.espresso:espresso-core:2.2.2’的使用会导致出现同包名类的重复被引用(javax.annotation.CheckForNull),导致无法编译打包。解决方案:删掉espresso的依赖
  • 会额外生成一些方法,方法数很容易爆表(eg:java.lang.IllegalArgumentException: method ID not in [0, 0xffff]: 65536 或者java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536)当然随着Android 5.0和multidex的出现,现在这个问题也不是问题了

    • multidex-1.0.1.aar去哪儿下载?

    其实他就在你的SDK里边
    android-sdk-linux/extras/android/m2repository/com/android/support/multidex/1.0.1/multidex-1.0.1.aar

拷贝到项目libs目录下添加依赖

dependencies {
    compile fileTree(include: ['*.jar', '*.arr'], dir: 'libs')
    compile 'com.android.support:multidex:1.0.1'
}

Tips

  • 成员变量或方法不要声明为私有,否则会在编译时出错(因为AA是在编译时产生一个他的直接子类,解析注释生成代码,而子类无法继承父类的私有变量)
  • 当你的Activity使用了@EActivity注解的时候 在 Mainfest 中注册MainActivity_ 而不是 MainActivity。
  • Drawable、Adapter、View或其他和Context相关的对象,都不可以被标注。如果标注了,将会引起这些资源或view的泄露,从而导致内存泄露。

你可能感兴趣的