AndroidでPOST送信の処理を実装したコードを使っていて、targetが2.3.3の場合何の問題もなかったのに、タブレット対応ということで4.2にレベルを上げた途端にエラー発生。
最初は何のことかさっぱりでした。
デバッグのコンソールを見たら何とFATAL ERRORで、android.os.NetworkOnMainThreadExceptionがどうしたこうした...。
調べてみたら、3.0以降「StrictMode」がデフォルトで有効になっており、メインスレッドでネットワーク処理を行うと例外がスローされるようになっておりました(TT)。
で、どうすりゃいいのとあれこれ調査した結果、AsyncTaskを継承したクラスを作ってそこで処理するようにすればいいのね、ってことが分かった。
これはその際記述したコードについてのメモ。
非同期処理した後、メインスレッドの関数をキックして処理を続行するようなこともしてみました。
AsyncTaskを継承したクラス(Asyncjob.java)
AsyncTaskでは4つほどのメソッドがありますが、比較的重要なのは以下の3つ。
doInBackground()
onProgressUpdate()
onPostExecute()
最も重要なのが、doInBackground。
メインスレッドとは別のスレッドで実行され、非同期で処理したい内容はここに記述します。
非同期処理の終了後にdoInBackgroundの戻り値が、onPostExecuteの引数として渡されます。
onPostExecuteはdoInBackgroundメソッドの実行後にメインスレッドで実行されるので、処理を引き継ぐ場合は、ここに記述。
onProgressUpdateは非同期処理の進行状況をどうにかする場合に使います。
コードの骨格はこんな感じ。
ここでは、doInBackground実行時に3つの引数を渡し、終了後にMainActivity.javaのpublic関数を実行させています。
extends AsyncTaskに続く3つのString型の引数はそれぞれ、doInBackground・onProgressUpdate・onPostExecuteに渡されます。
型はintegerとか他の型なんかも使えます。
(String...value)のような形になっているのは引数が配列で渡されるためです。
import android.os.AsyncTask;
public class AsyncJob extends AsyncTask<String,String,String> {
private MainActivity _main;
public AsyncJob(MainActivity main) {
super();
_main = main;
}
@Override
protected String doInBackground(String...value) {
String arg1 = value[0];//executeで渡される"A"
String arg2 = value[1];//executeで渡される"B"
String arg3 = value[2];//executeで渡される"C"
String res = "";
//ToDo
return res;
}
@Override
protected void onProgressUpdate(String... values) {
//
}
@Override
protected void onPostExecute(String result) {
_main.result_job(result);
}
}
-----------------------------------------
メインのアクティビティ(MainActivity.java)
以下を記述しておきます。
//非同期タスク宣言
private AsyncJob asynctask;
// 非同期処理を開始する
private void asynctask_job(){
//タスクの生成は都度おこなうこと
//AsyncTaskは1度しか実行できないので、使いまわさずに、必要な時に生成・実行させる
//でないと、2度目に実行した際に、例外エラーが発生する
//非同期タスクの生成
final AsyncJob asynctask = new AsyncJob(this);
//実行
asynctask.execute("A","B","C");
}
//onPostExecuteで実行される関数
public void result_job(String result){
Log.e("RES",result);
}