AsyncTask を使用してバックグラウンドで実行するコードがあります。コードは次のようになります。
private class MyAsyncTask extends AsyncTask<Void, Void, Object> {
public MyAsyncTask() {
// Some init. code
}
@Override
protected Object doInBackground(Void... params) {
// Doing some long running task.
Log.v(TAG, "Finished everything. Returning ...");
return result;
}
@Override
protected void onCancelled(Object result) {
// Either way, run the next one in the line.
Log.v(TAG, "Task cancelled");
}
@Override
protected void onPostExecute(Object result) {
Log.v(TAG, "Task Completed.");
}
}
Android 4 では問題なく動作しますが、2.3 で実行すると (現時点では HTC Wildfire が唯一のテスト用携帯電話です)、onPostExecute は呼び出されません。
からの最後のメッセージを確認できますが、またはdoInBackground
からのメッセージはありません。他の誰かが同じ問題に直面しましたか? 同様の問題について説明しているこのリンクを見つけましたが、明確な解決策 (の代わりに通常のスレッドを使用することを提案するだけ) も、まさに私が探しているものでもありません。onCancelled
onPostExecute
AsyncTask
助言がありますか?
乾杯
編集1:
わかりました。1 日かけてAsyncTask
、Handler
、およびMessage
2.3 と 4 のコードを読んだ後、何が起こっているのかについてより多くの手がかりが得られました。
まず、私のデザインについてもう少し詳しく説明します。アプリとアプリから開始された一部のサービスの両方で使用されるシングルトン クラスがあります。したがって、AsyncTask
上記のコードは、アクティビティ (シングルトンがアクティビティ経由でアクセスされると仮定) またはサービス (シングルトンがサービス経由でアクセスされる場合) から実行できます。
API 11 以降では、シングルトンにどのようにアクセスしても、問題なくonPostExecute
呼び出されます。API 10 以下では、シングルトンがアクティビティからアクセスされたonPostExecute
場合は問題なく呼び出されますが、サービス経由でアクセスされた場合はonPostExecute
呼び出されません。
ここでは、スタックする場所について詳しく説明します。AsyncTask
on 2.3 には、次のように内部に送信するためのFutureTask
オーバーライドdone
機能があります。Message
Handler
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
Message message;
Result result = null;
try {
result = get();
} catch (final InterruptedException e) {
android.util.Log.w(AsyncTask.LOG_TAG, e);
} catch (final ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (final CancellationException e) {
message = AsyncTask.sHandler.obtainMessage(AsyncTask.MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();
return;
} catch (final Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
message = AsyncTask.sHandler.obtainMessage(AsyncTask.MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};
次のコードの最後の 2 行は、クラスmessage.sendToTarget
を呼び出すはずの関数を呼び出していますが、そうではありません! ハンドラーへのコールバックがサービスからではなくアクティビティから発生する理由がわかりません! これを解決する方法はいくつかあります (コード内で API15+ の AsyncTask クラスを常に使用するだけです) が、これに関する知識がないため、この原因についての説明をいただければ幸いです。handleMessage
Handler
ありがとう