2014-04-04

[ハマりどころ] AndroidStudio+Gradle+Android Annotations

Android Annotationsとは

Javaによる記述を、アノテーションによる宣言に置き換えることで、
Androidのコードを短く簡潔にするライブラリ。
実装スピード、可読性、保守性の面でも嬉しい。ヽ(•̀ω•́ )ゝ✧
http://androidannotations.org/


インストールはこんな感じ

build.gradleにAndroidAnnotationsの依存関係を記述。
↓ページに全て書いてある。
http://www.jayway.com/2014/02/21/androidannotations-setup-in-android-studio/

  • buildscript.dependenciesにandroid-aptのクラスパスを追加
  • apply plugin: 'android-apt'の追加
  • apt.arguments.androidManifestFileの追加
  • dependenciesに apt "org.androidannotations:androidannotations:3.0+" を追加
  • dependenciesに compile "org.androidannotations:androidannotations-api:3.0+" を追加


build.gradleの全体像は以下のようになる。
JSONICとかAQueryのdependenciesはココでは無視してOK。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.2+'
    }
}

apply plugin: 'android'
apply plugin: 'android-apt'

apt {
    arguments {
        androidManifestFile variant.processResources.manifestFile
    }
}

repositories {
    mavenCentral()
}

dependencies {
    // Android Annotations
    apt "org.androidannotations:androidannotations:3.0+"
    compile "org.androidannotations:androidannotations-api:3.0+"
    // JSON manager
    compile 'net.arnx:jsonic:1.2.9'
    // AQuery
    compile 'com.googlecode.android-query:android-query:0.25.9'

    compile fileTree(dir: 'libs', include: '*.jar')
}

android {
    compileSdkVersion 17
    buildToolsVersion "19.0.0"

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }
        instrumentTest.setRoot('tests')
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}


Gradle Syncを実行する。


External Libraries に androidannotatinos-apiができていればOK。


使用例

本家。ひと目で効果のほどがわかるナイスなトップページ

サンプルが簡潔でわかりやすい



ハマりどころ

AndroidManifest.xmlで宣言しているActivity名の末尾に _ をつける必要あり。
(MainActivity -> MainActivity_)
実際の動作の際は、アノテーションを解釈して自動生成した子クラス(_つきクラス)を実行することになる。

が、Activity末尾に _ をつけても、ビルドの際にそんなActivityクラスないよと怒られる。
Build -> rebuild project
File -> Invalidate Caches / Restart...
で解消。
また、子クラスを自動生成して実行することから、
privateなフィールドやメソッドはprotectedに置き換える必要がある。


onCreate()の代わりに@AfterViewsのアノテーションをつけたメソッドを初期化メソッドとして使用する。

onCreate()内で@ViewByIdのフィールドにアクセスするとNullPointerExceptionで落ちる。
@ViewByIdが効いていないのだろうか、設定ミスったかと思ったが、
以下のページに答えがあった。
http://code.google.com/p/androidannotations/wiki/LayoutAndViews


When onCreate() is called, @ViewById fields are not set yet. 
Therefore, you can use @AfterViews on methods to write code that depends on views. 

@ViewByIdのフィールドがセットされた後の初期化処理、
Viewに対しての処理を行ないたい場合は、@AfterViewsを使ってねということ。

つまり、@ViewByIdのフィールドに対しての処理を行なわないならば、
onCreate()内に書いてOK。

処理の流れとしては以下のようになる。
onCreate() -> @ViewByIdフィールドへのセット -> @AfterViewsのメソッド



滑り出しで躓いたが、コードが短くなっていく過程は楽しい。
Javaは記述が冗長でストレスフルな言語だと思うこともあったが、
逆にそれだけ短くする楽しさもある