Android Dialog를 안전하고 간단하게 종료하기..

안드로이드 애플리케이션을 개발하다 보면, Dialog 부류의 위젯을 많이 사용하게 된다. 그리고 이 위젯을 화면에 보여주고 완료하면 dismiss()를 호출해서 종료를 시킨다. 이 과정에서 java.lang.NullPointerException이 발생할 수 있다. 그리고 Activty가 Dialog보다 먼저 종료(finish() 호출되는 등)가 되는 상황에서는 아래의 예외를 발생시킨다. java.lang.IllegalArgumentException: View not attached to window manager.

아래는 API 문서의 구조로, Dialog 부류의 최상위는 DialogInterface라는 것을 알 수 있다.

위 구조에서 dismiss()를 가지고 있는 클래스는 Dialog로, 이 클래스의 구조도는 다음과 같다.

ProgressDialog를 사용하면서 dismiss()를 하는 일반적이 코드는 다음과 같다.

if(progressdialog != null && progressdialog.isShowing())
{
   progressdialog.dismiss();
}

이 코드는 대체로 동작을 하지만, 위에서 언급한 예외가 발생할 수 있기에, 위의 코드를 try ~ catch로 감싸는 코드를 종종 보게 된다. 그래서 dismiss()를 안전하고 verbose하지 않게 처리하기 위해서 아래와 같은 간단한 유틸 클래스를 사용하면 좋다.

public class DialogDismisser {
	public static void dismiss(DialogInterface d) {
		if(d == null)
			return;
		
		try {
			if(d instanceof AlertDialog) {
				if(((AlertDialog) d).isShowing())
					((AlertDialog)d).dismiss();
				
				return;
			}
					
			if(d instanceof ProgressDialog) {
				if(((ProgressDialog) d).isShowing())
					((ProgressDialog)d).dismiss();
				
				return;
			}
			
			if(d instanceof Dialog) {
				if(((Dialog) d).isShowing())
					((Dialog)d).dismiss();
				
				return;
			}
		} catch(Exception e) {
			Log.e("dissmiss error", e);
		}
	}

	public static void dismiss(DialogInterface d1, DialogInterface d2) {
		dismiss(d1);
		dismiss(d2);
	}
}

이 클래스를 사용해서 각종 Dialog의 dismiss()를 안전하게 종료시킬 수 있다. 혹시 cancel()을 사용한다면 이 클래스와 동일한 형태로 작성해서 사용하면 된다.

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.