時間のかかる処理とプログレスダイアログ
もう1つのダイアログであるProgress Dialogは、基本的には、時間のかかる処理を行なうときに利用します。アプリケーション内で行なう処理には時間のかかるものがあります。このようなときに、なにも表示しないと、ユーザーは不安になり、画面のあちこちをタップしてしまったり、キーを操作してしまいます。
またAndroidでは、アプリケーションがクラッシュしたときに、他の機能(たとえば電話の着信など)に影響を与えないように、アプリケーションを監視しており、無反応な時間が長いとアプリケーションの強制終了のダイアログを表示させることがあります。これは、英語表記のダイアログのタイトル「Application Not Responding」からANRと呼ばれます。ANRはタッチやキー操作などに対して5秒以内に反応しなかったときに、BroadcastReceiverが10秒以内に実行を完了しないときに自動的に起動されます。ANRが起動すると、ユーザーに対して、アプリケーションを強制終了させるかどうかのダイアログが表示されてしまいます。そうなると、ユーザーは多くの場合、強制終了を選択してしまうため、アプリケーションは、想定していないところで終了させられることになります。
こうした問題を避けるためには、時間のかかる処理は別スレッドで行ない、メインスレッドではProgressDialogなどを使って、処理中であることを明確に示す必要があります。少なくともProgressDialogなどダイアログを表示させている間は、ANRに引っかかることはありません。
スレッドを使うもう1つの理由は、AndroidのGUI処理は完全な別スレッドではなく、アプリケーションのメインスレッドで実行されます。AlertDialogでshow()メソッドを実行すると、制御は完全にAndroid側に移ってしまい、ダイアログが閉じらるか、なんらかのイベント(別途イベントハンドラは定義しておく必要はありますが)が発生しない限り、アプリケーションのスレッドには戻ってきません。
また、これまでToastでメッセージを表示させていましたが、このToastによるメッセージ表示のあと処理を続けてしまうと、メッセージは表示されません。Toastメッセージを表示させたいなら、そのあとアプリケーションのスレッドは、イベント待ち状態にしなければなりません。
もう1つ注意しないといけない点ですが、GUIはアプリケーションのメインスレッドで実行されることから、GUI関連のAPI呼び出しなどは、すべてメインスレッド側で行なう必要があることです。つまり、時間のかかる処理のスレッドと、ProgressDialogを表示させるスレッドがあったとすると、時間のかかる処理のほうを別スレッドとして起動し、ProgressDialogを表示させるのはアプリケーションのメインスレッド側で行なわねばならないことです。
実際、別スレッド側でGUI関連の機能を使おうとすると、アプリケーションは停止させられます。GUI関連のAPIの中で、スレッドがチェックされており、メインスレッド以外からの呼び出しはすべてエラーとされます。というのは、別スレッドからのGUI操作を許すと、同じオブジェクトを複数のスレッドで同時に更新してしまう可能性もあるからです。このためGUIの更新処理が発生するAPI呼び出しはメインスレッドからのみ可能で、呼び出されたAPIは、メインスレッド上で動作します。
ただ、時間がかかる状態といっても、ANRの判断は絶対時間なのに対して、Androidの場合、機種による違い(CPUクロックやメモリ搭載量)などによって処理時間が変わってきます。開発時にエミュレータや高速な実機などでテストしていると、わからないこともあります。かといってすべての実機を用意するというわけにもいきません。
筆者が経験した範囲では大抵の処理でANRに引っかかるようなことはないのですが、配列のソートなどで要素数が数百程度で、独自のコンパレータなどを使うような場合には、ProgressDialogなどを表示させないと、ANRに引っかかるようです。
ProgressDialogには2つの種類があります。1つは、水平なバーが左端からぬりつぶされていくもので、経過途中で全体のどの程度に相当するのかがわかる場合、あるいは、何らかの値で進行状態を表現できる場合に利用するものです。ですが、処理によっては、どれぐらい時間がかかるのかも、現在どこまで処理が進んだのかもわからない場合があります。
たとえば、ファイルをダウンロードするような場合、ファイルサイズがわかっていれば、現在までにダウンロードしたデータサイズで、進行状態を表現することができます。ですが、今回のように並べ変え処理では、途中段階を表現する方法がありません。
このような場合には、短いバーを並べて、これが回転しているように見えるプログレスバーを使います。このプログレスバーは、表示させている間は、アニメーションが行なわれるため、ユーザーからは、処理が進んでいることがわかります。
この連載の記事
-
第11回
スマホ
アプリケーションをAndroidマーケットに登録する -
第10回
スマホ
ブロードキャストへの応答とタイマ割り込み -
第9回
スマホ
Androidアプリで複数の項目を表示するリストビューを使う -
第7回
スマホ
Androidアプリの設定画面を作成する -
第6回
スマホ
Androidアプリ内で表示されるメニューを作成する -
第5回
スマホ
インテントによるアプリケーションとアクティビティの呼出し -
第4回
スマホ
Androidアプリを構成する「アクティビティ」を実際に作る -
第3回
スマホ
アプリケーションの基本となる「アクティビティ」 -
第2回
スマホ
開発したアプリをエミュレーターやデバッガ上でテストする -
第1回
スマホ
Androidアプリの開発環境であるEclipseの使い方を知る - この連載の一覧へ