AndroidのService(サービス)メソッドを実行中に「通信中...」などと経過中のダイアログを表示したいなと思い、ProgressDialogを使用してみたのだが、
public boolean scrape(String siteurl, Bundle bundle) throws RemoteException {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setIcon(android.R.drawable.ic_dialog_alert);
dialog.setIndeterminate(true);
dialog.setTitle("Webスクレイピングサービス");
dialog.setMessage("通信中です...");
try {
dialog.show();
return WebScrapingService.this.doScrape(siteurl, bundle);
} finally {
dialog.dismiss();
}
}
ProgressDialog#showメソッドを呼んだ時に見たことも無い例外が発生した。
-
- スタックトレースの一部
07-08 01:34:53.807: ERROR/AndroidRuntime(593): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 07-08 01:34:53.807: ERROR/AndroidRuntime(593): at android.view.ViewRoot.setView(ViewRoot.java:509) 07-08 01:34:53.807: ERROR/AndroidRuntime(593): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177) 07-08 01:34:53.807: ERROR/AndroidRuntime(593): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 07-08 01:34:53.807: ERROR/AndroidRuntime(593): at android.app.Dialog.show(Dialog.java:241) :
ソースコードを追ってみると(ViewRoot#setView辺り)、どうやらサービスのコンテキスト(Context)でダイアログは表示できないらしい。(例外ではWindow階層に対象のViewを追加できないと怒られている)
解決策といっても、表示できないものは仕方が無い訳で、
1. ダイアログを表示するだけのActivityを用意して、サービスから呼び出す
2. 通知で良いのであればToastかNotificationを使用する
3. サービスは文字通り処理に徹し、GUIは全てActivity側でコントロールする(ダイアログもActivity側で表示する)
この中から選ぶしかなさそうだ。
1.は余計なActivityをわざわざ用意するのが嫌だし、2.は用途が限られる。やはりどう考えても3.だよな。