androidにおいて, AsyncTaskでスレッドをたててネットワーク接続を行う事は良くあると思います. ただ, キャンセル処理などまで考慮すると, いろいろ考えないといけない事が多くエラーの原因となります. こういった定型ルーチンはテンプレート化しておくと便利なので, メモしておきます.
順番が前後しますが, 通信タスクをonPause()でキャンセルする処理. _taskに通信用タスクを保存しておいて, ダイアログを閉じたりタスクをキャンセルしたりします. ここでダイアログを閉じなくても_task.cancelの中で呼び出される Asynctask#onCancelled で閉じるのですが, 一応年の為に. また, super.onPause()を呼び出す事を忘れない様に.
通信用のAsyncTaskはActivity内のprivate classとして定義しておきます. こうするとMyActivityのメンバ変数 (_task) や関数にアクセスできるので便利です. タスクの実行開始時 (onPreExecute()) はダイアログ生成して表示しています. setOnCancelListenerはbackボタンを押した時の処理です. これをいれておかないとbackボタンを押した時, ダイアログが閉じられてしまいます.
途中経過の表示部分. 途中経過を文字を表示するようにしています. 後でもでてきますが AsyncTask#cancelを呼び出しても, AsyncTaskのスレッドが即座に停止する訳ではありません. このため, _dialogがちゃんと存在するかのチェックを入れています.
doInBackground()がタスクの本体ですが, AsyncTask#cancelを呼び出してもタスク用スレッドが停止するのではなく, タスク終了後の処理 (onPostExecute)がキャンセルされるだけです. このため, doInBackgroundでは自分がキャンセルされていないか isCanceledでチェックする必要があります.
また, キャンセルされた場合は, onPostExecuteは呼び出されませんので, onCancelledでキャンセルされた時の後片付けを行う必要があります.
0 件のコメント:
コメントを投稿