我有AsyncFacebookRunner
将图片上传到Facebook。我想创建一个取消按钮,停止下载。
如何实现这一目标?
修改
这就是我使用它的方式:
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);
答案 0 :(得分: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
只会取消最后一个请求。
我建议返回线程,然后能够在其他地方中断它,但是你不能像这样改变方法的签名,并且创建一个新方法将无法使用其他{{1 } request
类中定义的方法。
相反,你可以做类似的事情:
AsyncFacebookRunner
你需要以某种方式为请求生成一个id,可以是简单的:
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();
}
}
}
答案 1 :(得分: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)
答案 2 :(得分:0)
这可能不是一个优雅的解决方案,但您可以中断AsyncFacebookRunner
正在使用的线程,处理生成的异常并优雅地取消通信。
或者您会考虑从存储库中分叉并将自己的取消方法添加到代码中吗?
修改强>
查看Google源存储库中AsyncTask
的实现方式。基本上你需要能够从任何设置取消标志的线程调用一个方法,这通常是一个
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;
}
当您取消任务时,您的方法会将此设置为true,您可以定期从AsyncFacebookRunner
主题进行检查。