2011. 1. 3. 11:47

다이얼로그 생성시 BadTokenException 이슈





요즘 어플리케이션 개발에 한창입니다. 점점 안드로이드 플랫폼에 익숙해져 가는것 같습니다. 그러나 때로는 명확해 보이는 코드가 오류를 던져 대면 당혹스러워 지는군요. 이번 경우가 그렀습니다.

오류 발생 코드

  1. public void onCreate( Bundle $bundle ) {   
  2.         super.onCreate( $bundle ) ;   
  3.         setContentView( R.layout.ui_setting ) ;   
  4.            
  5.         Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ;   
  6.         dialogShowBtn.setOnClickListener( this ) ;   
  7.     }   
  8.   
  9.     public void onClick(View v) {   
  10.         // TODO Auto-generated method stub   
  11.         switch( v.getId() ) {   
  12.         case R.id.dialogShowBtn :   
  13.             CustomDialog customDialog = new CustomDialog( getApplicationContext() ) ;   
  14.             customDialog.show() ;   
  15.             break ;   
  16.         }   
  17.     }  

오류 메세지

Uncaught handler: thread main exiting due to uncaught exception android.view.WindowManager$BadTokenException: Unable to add window — token null is not for an application

해결책

  1. public void onCreate( Bundle $bundle ) {   
  2.         super.onCreate( $bundle ) ;   
  3.         setContentView( R.layout.ui_setting ) ;   
  4.            
  5.         Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ;   
  6.         dialogShowBtn.setOnClickListener( this ) ;   
  7.     }   
  8.   
  9.     public void onClick(View v) {   
  10.         // TODO Auto-generated method stub   
  11.         switch( v.getId() ) {   
  12.         case R.id.dialogShowBtn :   
  13.             CustomDialog customDialog = new CustomDialog( this ) ;   
  14.             customDialog.show() ;   
  15.             break ;   
  16.         }   
  17.     }  

토의

일단 다이얼로그의 생성자에 인자로 보내는 Context를 getApplicationContext()로 얻어서 넘기는 대신에, Activity 자신을 직접 넘김으로써 오류를 잡는데는 성공했지만 아직까지는 명확하게 왜 이렇게 해야 하는지 알아가는 중입니다. 다만, 레퍼런스를 읽어보면 다이얼로그는 Owner Activity에 종속적으로 실행이 된다고 하는데 위에 오류 발생하는 코드를 보면 Activity를 알 길이 없습니다.

하지만 그렇다고 아래와 같은 코드도 BadTokenException 오류를 발생하기는 마찬가지였습니다.

  1. public void onCreate( Bundle $bundle ) {   
  2.         super.onCreate( $bundle ) ;   
  3.         setContentView( R.layout.ui_setting ) ;   
  4.            
  5.         Button dialogShowBtn = (Button) findViewById( R.id.dialogShowBtn ) ;   
  6.         dialogShowBtn.setOnClickListener( this ) ;   
  7.     }   
  8.   
  9.     public void onClick(View v) {   
  10.         // TODO Auto-generated method stub   
  11.         switch( v.getId() ) {   
  12.         case R.id.dialogShowBtn :   
  13.             CustomDialog customDialog = new CustomDialog( getApplicationContext() ) ;   
  14.             customDialog.setOwnerActivity( this ) ;   
  15.             customDialog.show() ;   
  16.             break ;   
  17.         }   
  18.     }  

관련예제