1

私はここで発狂します。簡単なことをしたい - 長いタスク (Web から複数のデータ オブジェクトをフェッチする) があり、それをキャンセルする機能が必要です。私はたくさんのことを(たくさん)試しましたが、何もうまくいきません

流れは次のようになります。

  1. ユーザーがボタンをクリックする

  2. AsyncTask作業を開始します ( 、ServiceIntentServiceおよびで試しましたLooper)

  3. タスクは、進行状況の更新に関する進行中の通知を追加することを含め、すべてを処理します

  4. 通知の意図には、進行中のタスクをキャンセルすることだけが目的であるという新しいアクティビティの呼び出しがあります。

  5. stopService()cancelActivityで Service/IntentService を呼び出そうとしたりLooper.quit()、Looper を実行しようとしました (AsyncTask で何を試したか覚えていません。キャンセルするための API があるかどうかはわかりません)。

私の観点では、最良のオプションは使用することですIntentService(いくつかのタスクを並べることができ、IntetService は希望どおりにそれを実行します)が、あらゆるタイプの実装の提案を受け入れます-私は何を気にしませんコードは、タスクをキャンセルするオプションがあるというだけです

よろしくお願いいたします。

ドロール

(私は寝ます - 同じ問題で8時間は多すぎます)

4

2 に答える 2

1

バックグラウンド ロジックで停止条件を認識できない場合は、タスクを停止するために使用する特定の操作は関係ありません。それをきれいに達成する唯一の方法は、バックグラウンド ワーカーが停止して誠意を持って終了することです。

バックグラウンド作業をキャンセルするために使用できるシナリオと解決策はほとんどありません。

  • バックグラウンド スレッドは、多くの短いステップを実行します (たとえば、いくつかのループを伴う計算)。この場合、isInterrupted()操作の間にいくつかのフラグ ( の可能性があります) を確認し、このフラグが操作を停止する必要があることを示している場合は終了します。
  • バックグラウンド スレッドがモニターで待機中です。バックグラウンド スレッドで呼び出しinterrupt()、例外ハンドラーで例外をキャッチし、適切な手順を実行してこのタスクを正常に終了し、終了します。
  • バックグラウンド スレッドは IO で待機中です。このユースケースは、一般的なケースでは解決が非常に困難です。ソケットを使用している場合は、このソケットを外部で閉じて、例外をキャッチできます。最悪のシナリオでは、スレッドが IO から戻った場合にスレッドがキャンセルされ、IO の結果を破棄する必要があることを認識している状態で、スレッドを放棄することができます。頻繁に行うとメモリ不足になるため、あまりお勧めしません。

いずれにせよ、タスクが停止される可能性を認識していない場合、タスクを停止する方法はありません (本当に悪いスレッドを強制終了する以外)。

于 2011-09-08T23:39:32.497 に答える
0

わかりました、私は自分がやりたいことに近いことをするように管理しました。

タスクをキューに入れるIntentServiceを使用しています。それぞれの新しいタスクはAsyncTaskです。AsyncTaskは、cancelActivityのpendingIntentを使用して通知を送信することから始まります。

通知をクリックすると、ユーザーはタスクの停止に関する警告ポップアップを受け取ります。stopService()彼が私のIntentServiceで行うよりも[はい]をクリックした場合。

IntentServiceに追加しました:

    @Override
public void onDestroy() {
    currentTask.cancel(true);
    if (mNotificationHelper != null)
        mNotificationHelper.completed();
    super.onDestroy();
    stopSelf();
}

私が追加したAsyncTaskで:

    @Override
protected void onCancelled() {
    isCanclled = true;
    httpClient.getConnectionManager().shutdown();
    mNotificationHelper.completed();
    if (mAsyncTaskListener != null)
        mAsyncTaskListener.AsyncTaskCanceled();
}

これにより、現在移動中のすべての接続が切断されます。作業を行う実際のコードでは、接続シャットダウンの例外をキャッチして処理する必要があります

したがって、最終的には、実際にAsyncTask / Serviceを停止するのではなく、公開するhttpClientので、非同期で接続を切断できるようになります。

少し醜いと思いますが、他に方法はありません

皆さん、ありがとうございました

于 2011-09-09T11:26:51.863 に答える