ひらい ぶらり Hi-Library

ぷろぐらみんぐについて。ときどきどうでもいいことについて。

AnimationListernerのonAnimationEndでViewをremoveViewするとNullPointerExceptionが起きる

タイトル通りなので、onAnimationEndの中でそのままremoveViewしてはいけない。
結論だけ言うと、Handlerを使って処理を遅延させて回避する。

@Override
public void onAnimationEnd(Animation animation) {

	new Handler().post(new Runnable() {
		@Override
		public void run() {
			((RelativeLayout)view.findViewById(R.id.some_layout)).removeView(someView);
		}
	});
}

参考:http://stackoverflow.com/questions/5569267/nullpointerexception-that-doesnt-point-to-any-line-in-my-code

さて、このぬるぽが何なのか考えてみる。
StackTraceを見ると別にremoveするときに対象のビューがNullというわけでは無さそう。

04-06 10:37:43.610: ERROR/AndroidRuntime(23203): java.lang.NullPointerException
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2122)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.drawChild(ViewGroup.java:2506)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2123)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.View.draw(View.java:9032)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.widget.FrameLayout.draw(FrameLayout.java:419)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1910)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.draw(ViewRoot.java:1608)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1329)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1944)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.os.Looper.loop(Looper.java:126)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at android.app.ActivityThread.main(ActivityThread.java:3997)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at java.lang.reflect.Method.invokeNative(Native Method)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at java.lang.reflect.Method.invoke(Method.java:491)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-06 10:37:43.610: ERROR/AndroidRuntime(23203):     at dalvik.system.NativeStart.main(Native Method)

ぱっと見た感じでは、Viewを描画しようとして、そのviewがremoveされたせいでエラーになっているように見える。
つまりonAnimationEndメソッドを実行してる段階では、見た目上のアニメーションを終了しているものの、Viewを描画する処理は終わっておらず
onAnimationEnd中で処理をするとヌルポになる。っぽい。
なので、Handlerで処理を遅延してやることで回避できた。とおもわれる。