1

AsyncFacebookRunnerFacebookに画像をアップロードするものがあります。ダウンロードを停止するキャンセルボタンを作成したい。

どうすればそれを達成できますか?

編集:

これが私がそれを使う方法です:

byte[] data = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
data = baos.toByteArray();
Bundle params = new Bundle();
params.putByteArray("picture", data);
AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
mAsyncRunner.request("me/photos", params, "POST", 
new PhotoUploadListener(dialog), null);
4

3 に答える 3

1

いつでもクラスを拡張してメソッドAsyncFacebookRunnerをオーバーライドできます。 このようなもの:request

public class CancelableAsyncFacebookRunner extends AsyncFacebookRunner {
    private Thread requestThread;

    public AsyncFacebookRunner(Facebook fb) {
        super(fb);
    }

    @Override
    public void request(final String graphPath,
            final Bundle parameters,
            final String httpMethod,
            final RequestListener listener,
            final Object state) {

        this.requestThread = new Thread() {
            @Override
            public void run() {
                try {
                    String resp = fb.request(graphPath, parameters, httpMethod);
                    listener.onComplete(resp, state);
                } catch (FileNotFoundException e) {
                    listener.onFileNotFoundException(e, state);
                } catch (MalformedURLException e) {
                    listener.onMalformedURLException(e, state);
                } catch (IOException e) {
                    listener.onIOException(e, state);
                }
            }
        };
    }

    public void cancel() {
        this.requestThread.interrupt();
    }
}

テストされていませんが、一般的なアイデアを提供する必要があります。


編集

考えてみると、 を使用AsyncFacebookRunnerして複数のリクエストを行い、cancelは最後のリクエストのみをキャンセルするため、これはあまり意味がありません。

スレッドを返し、それを別の場所で中断できるようにすることをお勧めしますが、このようにメソッドのシグネチャを変更することはできず、新しいメソッドを作成してもクラスrequestで定義された他のメソッドを使用できません。AsyncFacebookRunner

代わりに、次のようなことができます。

public class CancelableAsyncFacebookRunner extends AsyncFacebookRunner {
    private Hashtable<String, Thread> requestThreads;

    public AsyncFacebookRunner(Facebook fb) {
        super(fb);
        this.requestThreads = new Hashtable<String, Thread>();
    }

    @Override
    public void request(final String id, 
            final String graphPath,
            final Bundle parameters,
            final String httpMethod,
            final RequestListener listener,
            final Object state) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    String resp = fb.request(graphPath, parameters, httpMethod);
                    requestThreads.remove(id);
                    listener.onComplete(resp, state);
                } catch (FileNotFoundException e) {
                    requestThreads.remove(id);
                    listener.onFileNotFoundException(e, state);
                } catch (MalformedURLException e) {
                    requestThreads.remove(id);
                    listener.onMalformedURLException(e, state);
                } catch (IOException e) {
                    requestThreads.remove(id);
                    listener.onIOException(e, state);
                }
            }
        });

        this.requestThreads.put(id, thread);
        thread.start();
    }

    public void cancel(String id) {
        if (this.requestThreads.containsKey(id) {
            this.requestThreads.get(id).interrupt();
        }
    }
}

リクエストに対して何らかの方法で ID を生成する必要があります。次のような単純なものにすることができます。

String.valueOf(System.currentTimeMillis());
于 2012-06-20T21:38:31.703 に答える
0

あなたはこのようなことをすることができます:

AsyncFacebookRunner fbRunner;

@Override
public void onClick(View v){
    fbRunner.cancel(true);
}

これを呼び出してもonPostExecute(Object)は呼び出されないため、これに注意する必要があります

http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean

于 2012-06-13T00:18:32.200 に答える
0

これは洗練された解決策ではないかもしれませんが、AsyncFacebookRunner使用しているスレッドを中断し、結果の例外を処理し、通信を正常にキャンセルできる場合があります。

あるいは、リポジトリからフォークして、独自のキャンセル メソッドをコードに追加することを検討しますか?

編集

AsyncTaskがどのように Google ソース リポジトリに実装されているかを見てください。基本的に、キャンセルされたフラグを設定するスレッドからメソッドを呼び出すことができる必要があります。これは通常、

private volatile boolean cancelled = false;
// volatile ensures you always get up to date value when checking across threads

public void cancel() {
    cancelled = true;
}

public boolean isCancelled() {
    return cancelled;
}

AsyncFacebookRunnerタスクをキャンセルすると、メソッドはこれを true に設定し、スレッドから定期的にチェックします。

于 2012-06-19T14:06:21.363 に答える