Android Annotationには@UiThreadという便利なAnnotationが有ります。
例えば次のようにするだけでどんなスレッドから呼ばれてもこのメソッドはUiThreadで実行されます。
Androidのウィジェットはスレッドセーフではなく必ずUIThreadから呼ぶ必要があるのでこの機能がとても便利です。
今まで同じようなことをしようと思ったらハンドラーを使ったりとわりと面倒な実装が必要でした。
ということで、Android Annotationで@UiThreadを使っている人は多いと思うのですが、
ある日突然、@UiThreadで実行している処理がエラーで落ちるようになりました。
エラー内容は
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
典型的なUIThread以外でWidgetをさわろうとした場合に発生する例外です。
結論から言うと、Android Developer Toolsに新しく入ったandroid support annotationの@UiThreadと名前がかぶっていたため
何かのタイミングでAndroid support libraryのインポート文が外れて代わりにAndroid support annotationのものに置き換わっていました。
こちら、名前は同じですがやることは全然違っていて、Android AnnotationはUi threadのハンドラーに処理を投げるようなロジックを影で実装してくれるのに対して、Android Support AnnotationはAsyncTaskや@WorkerThread指定されたメソッドのような明らかにUIThreadではないとされる場所から呼び出すとエラーを返すというチェックロジックしかありません。
ということで、@UiThreadが効かなくなってしまった時はimport文を見なおして
となっていたら
に変更しましょう。
例えば次のようにするだけでどんなスレッドから呼ばれてもこのメソッドはUiThreadで実行されます。
@UiThread
void doUiThread(){
mTextView.setText("It's OK");
}
Androidのウィジェットはスレッドセーフではなく必ずUIThreadから呼ぶ必要があるのでこの機能がとても便利です。
今まで同じようなことをしようと思ったらハンドラーを使ったりとわりと面倒な実装が必要でした。
ということで、Android Annotationで@UiThreadを使っている人は多いと思うのですが、
ある日突然、@UiThreadで実行している処理がエラーで落ちるようになりました。
エラー内容は
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
典型的なUIThread以外でWidgetをさわろうとした場合に発生する例外です。
結論から言うと、Android Developer Toolsに新しく入ったandroid support annotationの@UiThreadと名前がかぶっていたため
何かのタイミングでAndroid support libraryのインポート文が外れて代わりにAndroid support annotationのものに置き換わっていました。
こちら、名前は同じですがやることは全然違っていて、Android AnnotationはUi threadのハンドラーに処理を投げるようなロジックを影で実装してくれるのに対して、Android Support AnnotationはAsyncTaskや@WorkerThread指定されたメソッドのような明らかにUIThreadではないとされる場所から呼び出すとエラーを返すというチェックロジックしかありません。
ということで、@UiThreadが効かなくなってしまった時はimport文を見なおして
import android.support.annotation.UiThread;
となっていたら
import org.androidannotations.annotations.UiThread;
に変更しましょう。