본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[Android/안드로이드] ViewFlipper 의 IllegalArgumentException.

by 돼지왕 왕돼지 2012. 4. 10.
반응형



안녕하세요 돼지왕 왕돼지입니다.

ViewFlipper 를 사용하면서 Orientation 을 변경하니 IllegalArgumentException 이 발생하더군요.
로그는 다음과 같습니다.

04-10 22:22:25.201: W/dalvikvm(15721): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)

04-10 22:22:25.211: E/AndroidRuntime(15721): FATAL EXCEPTION: main

04-10 22:22:25.211: E/AndroidRuntime(15721): java.lang.IllegalArgumentException: Receiver not registered: android.widget.ViewFlipper$1@4055f160

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:634)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:888)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.View.dispatchDetachedFromWindow(View.java:6257)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1250)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1248)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1868)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewRoot.doDie(ViewRoot.java:2958)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.ViewRoot.die(ViewRoot.java:2928)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:257)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:445)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3268)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3373)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.ActivityThread.access$1600(ActivityThread.java:135)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1058)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.os.Handler.dispatchMessage(Handler.java:99)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.os.Looper.loop(Looper.java:150)

04-10 22:22:25.211: E/AndroidRuntime(15721): at android.app.ActivityThread.main(ActivityThread.java:4385)

04-10 22:22:25.211: E/AndroidRuntime(15721): at java.lang.reflect.Method.invokeNative(Native Method)

04-10 22:22:25.211: E/AndroidRuntime(15721): at java.lang.reflect.Method.invoke(Method.java:507)

04-10 22:22:25.211: E/AndroidRuntime(15721): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)

04-10 22:22:25.211: E/AndroidRuntime(15721): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)

04-10 22:22:25.211: E/AndroidRuntime(15721): at dalvik.system.NativeStart.main(Native Method)


Log 정보와 인터넷 search 결과를 살펴서 원인을 분석해 보았습니다.

Exception 의 이유는 onAttachedToWindows() 가 불리기 전에 onDetachedFromWindow() 가 불리는 문제입니다. 즉, Window 에 붙지도 않았는데, window 로부터 detach 를 부르려 하니 IllegalArgument ( 잘못된 argument ) Exception 이 발생하는 것이죠. 이 이슈는 Froyo( 2.1 )부터 GingerBread( 2.3.3 ) 까지 나타납니다. ( HoneyComb 과 ICS 는 따로 테스트해보질 못했습니다. )

그럼 이 녀석을 어떻게 고쳐야 하느냐? 가장 간단한 방법은, framework 를 손댈 수 없다면, 우리가 exception을 catch 해주는 것입니다.

@Override
protected void onDetachedFromWindow(){
   try{
      super.onDetachedFromWindow();
   }
   catch( IllegalArgumentException e ){
      stopFlipping();
   }


요런식으로 무시해주는 방법입니다. 무시하기만 하는것이 아니고 왜 stopFlipping() 을 호출해주냐구요? stopFlipping() 을 호출하면 updateRunning() 을 호출하는 것과 같은 효과입니다. 

이 방법 이외에도, orientation 이 변경될 때 일정한 시간을 두고, orientation 전환을 초래하는 수단도 있습니다. 하지만, 단말마다 시간설정에 차이가 있을 수 있고, 즉각적인 변환을 원하는 경우도 있기 때문에 이 방법을 권장하는 바입니다.

도움이 되셨다면 손가락 꾸욱~




 
반응형

댓글