LoginSignup
0
0

More than 5 years have passed since last update.

Android AnnotationでNullPointerException

Last updated at Posted at 2015-08-29

投稿していない日数を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を触ることもあり、かなり苦戦しました・・・

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0