投稿していない日数をtwitterで通知しているのに、200日以上ぶりの投稿・・・
先日久しぶりにAndroidを触った際、以前から触ってみたいと考えていたAndroidAnnotationを使って見ることに。
Android Annotationとは
AndroidAnnotationの詳しい説明はggって欲しいですが、簡単にはAndroidのxmlのviewやitemとの連携をannotationで書け、コード記述量を減らせるライブラリです。
具体的には、
@EActivity(R.layout.test)
public class Test extends Activity {
@ViewById(R.id.mySurfaceView)
TestSurfaceView tsv;
@Click(R.id.leftButton)
protected void leftButtonClick(final View view) {
// TODO
}
のように書くことがで、viewやview itemの紐つけ、押した際の処理を定義できます。
これによって今までfindViewByIdやonClickListenerを複数定義してごちゃごちゃになっていたところを、annotation付きのメソッドで簡略に記述できます。
今回の発生した問題
今回はこれを利用してコード量を減らし、一部のviewはインスタンスを保持し、メソッドを呼び出せるようにしました。
@EActivity(R.layout.test)
public class Test extends Activity {
@ViewById(R.id.mySurfaceView)
TestSurfaceView tsv;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
// 試しにメソッド呼びだし
tsv.doSomething();
}
}
しかし、これを実行するとNullPointerExceptionが発生します。今までonCreateでfindViewByIdを呼び出していたので、なぜNullなのか分からず、混乱しました。
そのため調べてみると、どうやらannotationをつけたviewは自動でインジェクションされるものの、onCreateの時点ではインジェクションされていないそうです・・・
じゃあどうするのか?
onCreateでは挿入されませんが、インジェクションされた後に呼び出すことを指定できるannotationがあります。@AfterViewをつけるとそのメソッドはインジェクション後に呼び出されます。
つまり、以下のように書けば解決します。
@EActivity(R.layout.test)
public class Test extends Activity {
@ViewById(R.id.mySurfaceView)
TestSurfaceView tsv;
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
}
@AfterViews
void initialize(){
// Wait for surfaceview ready
// 試しにメソッド呼びだし
tsv.doSomething();
}
}
久しぶりにAndroidを触ることもあり、かなり苦戦しました・・・