Androidでスレッドを使う理由

http://ascii.jp/elem/000/000/548/548698/index-4.htmlAndroidでスレッドを使うべき理由が記載されていた。

  • ANR
  • GUIがメインスレッドで実行されているため

まずANR(Android Not Response)はアプリケーションが絶対時間で5秒間反応しなくなるとAndroidの監視タスクがANRメッセージを表示するという機能。

この機能が問題になるのは例えばアプリケーション上で配列の組み替えをして時間がかかるときに、処理としては動いているのにアプリケーションとしては監視タスクに反応を返さなくなる。そのために監視タスクがアプリケーションがおかしくなっていると判断して、処理の途中のアプリケーションを停止してしまうというシナリオが考えられる。

ANRを避けるためには時間がかかる処理をスレッド側に移行してメインスレッドは常に監視タスクに反応できるようにするのが望ましい。

ANRについては理解するのは難しくないのだが次の"GUIがメインスレッドで実行されているため"という理由がよくわからなかった。

調べているうちにAndroid Dev Guideに以下のような記載があるのを見つけた。

The setup is simple. Most of the code needed to create a progress dialog is actually involved in the process that updates it. You might find that it's necessary to create a second thread in your application for this work and then report the progress back to the Activity's UI thread with a Handler object. If you're not familiar with using additional threads with a Handler, see the example Activity below that uses a second thread to increment a progress dialog managed by the Activity.

Dialogs  |  Android Developers

要約するとProgressDialogを使うときには別のスレッドを使ったほうがよいという話。おそらくであるが以下のようなシナリオだと考えられる。

まず前提として

  • GUIはメインスレッド上で実行されている。

これが重要。プログレスバーで進捗を表示するためには当然進捗度合いを計算しなければならない。しかしGUIがメインスレッド上で実行されていることから、メインスレッド上での処理はできない。そのために進捗を計算する別のスレッドを用意しておきその進捗度合いによりメインスレッド上に値を返す(call back)して、メインスレッド上でプログレスバーを更新するということではないかと思う。

そうすると下記の一文もshow()メソッドでは進捗が終わったタイミングでの自動的にダイアログを閉じるという動作ができないために、進捗を表示するためにはプログレスバーを使うという意味にとることができる。

AlertDialogでshow()メソッドを実行すると、制御は完全にAndroid側に移ってしまい、