3

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からのメッセージはありません。他の誰かが同じ問題に直面しましたか? 同様の問題について説明しているこのリンクを見つけましたが、明確な解決策 (の代わりに通常のスレッドを使用することを提案するだけ) も、まさに私が探しているものでもありません。onCancelledonPostExecuteAsyncTask

助言がありますか?

乾杯

編集1:

わかりました。1 日かけてAsyncTaskHandler、およびMessage2.3 と 4 のコードを読んだ後、何が起こっているのかについてより多くの手がかりが得られました。

まず、私のデザインについてもう少し詳しく説明します。アプリとアプリから開始された一部のサービスの両方で使用されるシングルトン クラスがあります。したがって、AsyncTask上記のコードは、アクティビティ (シングルトンがアクティビティ経由でアクセスされると仮定) またはサービス (シングルトンがサービス経由でアクセスされる場合) から実行できます。

API 11 以降では、シングルトンにどのようにアクセスしても、問題なくonPostExecute呼び出されます。API 10 以下では、シングルトンがアクティビティからアクセスされたonPostExecute場合は問題なく呼び出されますが、サービス経由でアクセスされた場合はonPostExecute呼び出されません。

ここでは、スタックする場所について詳しく説明します。AsyncTaskon 2.3 には、次のように内部に送信するためのFutureTaskオーバーライドdone機能があります。MessageHandler

        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 クラスを常に使用するだけです) が、これに関する知識がないため、この原因についての説明をいただければ幸いです。handleMessageHandler

ありがとう

4

1 に答える 1

-2

公式ドキュメントは非常に詳細です。それを読んでみてください。

このリンクを確認してください。

http://foo.jasonhudgins.com/2010/05/limitations-of-asynctask.html

OK~ 注意:

cancel(boolean) メソッドを呼び出すと、onCancel 関数が実行されます。この関数を呼び出しましたか?

于 2012-12-16T03:08:50.463 に答える