天天看點

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配置使用
  5. 将Factory Path項的第一項勾上,并且點選Add JARs按鈕
    AndroidAnnotations配置使用
  6. 找到該項目之前建立的compile-libs檔案中添加的jar包,OK
    AndroidAnnotations配置使用
  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[]?.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=
    @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的洩露,進而導緻記憶體洩露。