0

AsynTask のキャンセルに関する他の投稿をいくつか見ましたが、どれも問題を解決しているとは思いません。次のシナリオを想像してください。

public class TestTask extends AsyncTask<Void, Void, Object> {

@Override
protected void onCancelled(Object result) {
    running = false;
    Log.i("Test", "onCancelled");
}

@Override
protected Object doInBackground(Void... params) {
        try {
            Log.i("Test", "cancelling");
            cancel(true);
            Thread.sleep(5000);
            Log.i("Test", "Past sleep");
        } catch (InterruptedException e) {
            Log.i("Test", "InterruptedException", e);
        }

    return null;
}

}

たとえば、サーバーの json リクエストへの応答が遅い場合など、ダウンロードの途中でこの 20 秒の長いリクエストをキャンセルしたいとします。したがって、 Thread.sleep(5000) は、キャンセルしたい HttpGet リクエストである可能性があります。ただし、cancel メソッドは final としてマークされているため、オーバーライドして get.abort() を呼び出すことはできません。onCancel フックは、doInBackground の後に発生し、UI スレッドに戻ります。HttpGet リクエストが開始されると、isCancel をチェックしても何の役にも立ちません。

これを解決する方法は、AsynTask で abort() メソッドを作成し、それを呼び出すことです。

public void abort() {
   get.abort();
   cancel(true);
}

しかし、これは Android の粒度に少し反するようです。リクエストをキャンセルするより良い方法はありますか?

4

2 に答える 2

0

これが該当するかどうかはわかりませんが、ダウンロード タスクを実行するエグゼキュータ サービスを使用して別のスレッドを作成し、isCancelled()内部をチェックし続けるか、doInBackground()または将来のオブジェクトが返されるまで、どちらか先に発生する方を確認することができます。

@Override
protected Object doInBackground(Void... params)
{
    Callable<Void> downlaodTask = new Callable<Void>()
    {
        @Override
        public Void call() throws Exception
        {
            // download task here

            return null;
        }
    };

    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Void> future = executor.submit(downlaodTask);

    while(true) // check every second
    {
        try
        {
            future.get(1, TimeUnit.SECONDS); // wait until the download task finishes with 1 second as a timeout
            break;
        }
        catch(TimeoutException e)
        {
            if(isCancelled())
            {
                executor.shutdownNow(); // or abort() or both
                break;
            }
        }
    }

    return null;
}
于 2013-03-01T22:34:38.670 に答える