このページの本文へ

これで作れる! Androidのアプリケーション 第8回

Androidアプリに必要なダイアログを作る

2010年08月20日 12時00分更新

文● 塩田紳二

  • この記事をはてなブックマークに追加
  • 本文印刷

時間のかかる処理とプログレスダイアログ

 もう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つは、水平なバーが左端からぬりつぶされていくもので、経過途中で全体のどの程度に相当するのかがわかる場合、あるいは、何らかの値で進行状態を表現できる場合に利用するものです。ですが、処理によっては、どれぐらい時間がかかるのかも、現在どこまで処理が進んだのかもわからない場合があります。

写真はSDKサンプルのApiDemoのもの。最大値のわかっている数値で進行状態を確認できる場合には、この形式のプログレスバーが利用できる

 たとえば、ファイルをダウンロードするような場合、ファイルサイズがわかっていれば、現在までにダウンロードしたデータサイズで、進行状態を表現することができます。ですが、今回のように並べ変え処理では、途中段階を表現する方法がありません。

 このような場合には、短いバーを並べて、これが回転しているように見えるプログレスバーを使います。このプログレスバーは、表示させている間は、アニメーションが行なわれるため、ユーザーからは、処理が進んでいることがわかります。

途中状態のチェックができない場合、このような形式のProgressDialogを使う。アニメーション部分は、画面サイズ、密度などにより違っているが、基本的には、バーが回転するアニメーションになる

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン