難しい事を考えずにANRを回避する実装方法についての説明。ANRとは=・・・は応答していません。Respondingでアプリケーションが応答しない状態になったとOS側で認識して「こいつ固まっちゃいましたけど、どーします?」って聞いてくるアレです。ANRを起こすコード簡単な例を以下に示します。text_view.setText("起きました!");}ActivityにはボタンとTextViewが一個ずつ配置されていて、ボタンを押すとTextViewのメッセージを変更した後、10秒寝て、起きるとまたTextViewのメッセージを変更するだけの処理です。このコードでは以下の問題があります。ボタンを押しても直後のTextViewの変更「寝ています」が反映しない。ボタンを押すと10秒間ユーザはアプリケーションに対して何をやっても反応しない。操作をしようとすると、しばらくしてANRが発生してOSがアプリを止めようとしてくる。これを回避しようと思った場合、以下のようにAsyncTaskで処理を置き換える事が可能です。Threadが云々いろいろあるのですが、機械的に置き換える形でやってみたいと思います。書き換え方は以下の3ステップGUIに手を出している部分(これはすばやく終わる必要があります)は、AsyncTask内に入れない(本当はonPreExecuteに入れてやるのでもいいんですけど)GUIに手を出していない処理に時間のかかる部分を上記のようなAsyncTask内のdoInBackgroundの中に書く。この関数の中でGUIに直接手を出してはいけません。2の処理が終了後に実行したい処理(主にGUIに関する更新など)を別の関数に移動。ここではsleepTenSecsDone()にしてます。onPostExecute内で3の関数を呼び出す様にする。text_view.setText("起きました!");}ここまででANRを回避そのものはできますが、以下に示すような問題があるためこれだけだと対応としては不十分です。第一にsleepTenSecs()の呼び出しはすぐに終わって戻ってきてしまいますが、背後では時間のかかる処理が進行中です。この時にもう一度ユーザがボタンを押すとsleepTenSecsがまた呼ばれてしまいます。このため多重に処理がかからない様にする必要があります。いくつか方法が考えられますが、まず単純に「処理の開始時1の処理中にボタンをbutton.setEnabled(false);をボタンに対して実行してボタンを押せない様にする」というのがあります。この場合、2の処理が他の全然関係無い処理と並行に実行されても問題無い事を保障する必要があります。3の処理の中や適当なところでボタンをenableにする処理も必要になるでしょう。Dialogを表示してActivityに対するユーザ操作をさせない方法です。良くProgressDialogを表示してActivityには触れないようにするアレです。こちらの方であればユーザがアプリケーションを操作する事ができなくなるため、並行で複数の処理が走る事を気にする必要がないので一般的にはこちらの方が多いように思います。AsyncTaskのインスタンスを作る直前で以下の様にdialogを作成するコードを挟みます。dialog.show();これだけだとProgressDialogを閉じる処理が無いので、AsyncTaskが終わっても操作ができないままになってしまいます。処理完了後にdialog.dismiss();を入れておきます。finalを入れてあります(^_^;)。}これでActivityに対する操作を無効化できます。いうわけで、最初のコードをANRが出ない様に書き換えたコードを以下に示します。text_view.setText("起きました!");}とりあえず、これでANRを回避する事は出来ますが、いくつか改良すべき点もあります。処理をキャンセルする事が出来ない。Threadの違い、AsyncTask、Handler回りを勉強してみてください。ちなみにAndroidの本が無くても、Java関連の本がある場合、Swing関連が乗っているような本であればSwingWorker周りを調べると恐らく多少は参考になると思います。Threadを実行する形をとる必要があるからです。今度書店行ったら探してみます。