我正在从异步任务的doInBackground调用另一个类的方法。 现在我需要在调用cancel时停止下载。我不知道在哪里检查isCancelled()的值。
class myasync extends Asynctask{
protected String doInBackground(String... sURL) {
abc = new abc();
abc.getURLResult(sURL[0])
}
}
class abc()
{
getURLResult(String URL)
{
for(int i=0; i<fp.size(); i++){
//some text to download
}
}
}
class myclass
{
myclass()
{
myasync = new myasync();
myasync.execute("http:\\");
}
stopDownload()
{
myasync.cancel(true);
}
}
编辑: 通过结合以下两个答案使用了以下解决方案:
1. myclass.cancel1(true);
class myclass
{
myclass()
{
myasync = new myasync();
myasync.execute("http:\\");
}
stopDownload()
{
myasync.cancel1(true);
}
}
2.
class myasync extends Asynctask{
protected String doInBackground(String... sURL) {
abc = new abc();
abc.getURLResult(sURL[0])
}
cancel1()
{
abc.cancel();
}
}
3.
class abc()
{
private boolean cancel = false;
getURLResult(String URL)
{
for(int i=0; i<fp.size(); i++){
//some text to download
if(cancel)
break;
}
}
cancel()
{
cancel = true;
}
}
上述方法正在运行。但是,方法myclass.stopDownload()
正在UI线程中运行,因此myasync.cancel1()
和abc.cancel()
正在运行UI线程。并且myAsync.doInBackground()
和abc.getURLResult()
正在单独运行。我不太了解进程间通信。我希望这是正确的事情。
答案 0 :(得分:0)
不是很好,但你可以通过添加一个静态变量isDownloading
来做这样的事情:
protected String doInBackground(String... sURL) {
abc = new abc();
abc.getURLResult(sURL[0])
}
}
class abc()
{
getURLResult(String URL)
{
for(int i=0; i<fp.size(); i++){
if(!myclass.isDownloading){ //ADDED
break; // or Return or handle Cancel
}
//some text to dopwnload
}
}
class myclass
{
public static boolean isDownloading; // ADDED
myclass()
{
myasync = new myasync();
isDownloading = true; // ADDED
myasync.execute("http:\\");
}
stopDownload()
{
isDownloading = false; // ADDED
myclass.cancel(true);
}
}
答案 1 :(得分:0)
<强>更新强>
从AsyncTask取消doc。我们必须检查异步任务是否被取消了。
调用此方法将导致调用onCancelled(Object) 在doInBackground(Object [])返回后的UI线程上。打电话给这个 方法保证永远不会调用onPostExecute(Object)。后 调用此方法时,应检查返回的值 isCancelled()定期从doInBackground(Object [])来完成 尽早完成任务。
为此,请将asyncTask本身作为参数与URL一起发送到getURLResult:
protected String doInBackground(String... sURL) {
new abc().getURLResult("http://...", this); // this here is the asyncTask itself.
}
getURLResult(String URL, myasync myAsyncTask)
{
for(int i=0; i<fp.size(); i++){
if(myAsyncTask.isCancelled()){
break;
}
}
}
不要像其他建议那样使用布尔值。它根本不安全,因为可以启动另一个AsyncTask。它是一个后台线程。你不能保证哪个会首先检查布尔值。可以取消所有AsyncTasks。
旧帖子:
您需要检查取消以确保取消的唯一地方!在onPostExecute
上。您无法保证在调用cancel
方法时取消了异步任务。因此,您需要检查客户端应用程序是否要求取消它,并且不再需要返回的数据。
private boolean askedForCancellation = true;
@Override
protected void onPostExecute(Object response) {
if (!askedForCancellation)
// parse response
else
// ignore. or send message to activity to stop loading if you didn't already did that when called cancel method.
}
要实现这一点,请将以下取消方法添加到 AsyncTask :
public final boolean cancel(boolean mayInterruptIfRunning) {
askedForCancellation = true;
return mFuture.cancel(mayInterruptIfRunning);
}
在你班上:
myasync.cancel(true);
myasync = null;
将myasync设置为null即可。因为,你不能再使用它再次执行。你会得到一个运行时错误。你需要重新初始化它。
检查AsyncTask是否要求取消。检查是否值 myasync等于null。记得AsyncTask要求得到的 取消,但没有取消,因为无法保证 打电话取消时取消。你做的是忽略了 对
的回复onPostExecute
到目前为止,我在超过15个应用程序中使用了这种方法。没有错误,没有意外的行为。