在Android应用开发过程中,为了防止UI线程堵塞,耗时的工作都应该另起一个后台线程来完成,其中AsyncTask就是其中的一种方式。最近在案子中需要“停止/取消”某个AsyncTask,在网上查了些资料,这里做个笔记。

查看AsyncTask.java文件,其中有个cancel()函数,可以通过调用cancel(true)来停止正在运行的AsyncTask。

    /**
* <p>Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
* then the <tt>mayInterruptIfRunning</tt> parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.</p>
*
* <p>Calling this method will result in {@link #onCancelled(Object)} being
* invoked on the UI thread after {@link #doInBackground(Object[])}
* returns. Calling this method guarantees that {@link #onPostExecute(Object)}
* is never invoked. After invoking this method, you should check the
* value returned by {@link #isCancelled()} periodically from
* {@link #doInBackground(Object[])} to finish the task as early as
* possible.</p>
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete.
*
* @return <tt>false</tt> if the task could not be cancelled,
* typically because it has already completed normally;
* <tt>true</tt> otherwise
*
* @see #isCancelled()
* @see #onCancelled(Object)
*/
public final boolean cancel(boolean mayInterruptIfRunning) {
mCancelled.set(true);

  值得注意的是,调用cancel(true)函数需要注意以下几点:

  1.当AsyncTask已经完成,或则以及被取消,亦或其他原因不能被取消,调用cancel()会失败;

  2.如果AsyncTask还没有开始执行,调用cancel(true)函数后,AsyncTask不会再执行;

  3.如果AsyncTask已经开始执行,参数mayInterruptIfRunning决定是否立即stop该Task;

  4.调用cancel()后,doInBackground()完成后,不再调用onPostExecute(),而是执行onCancelled();

  下面是一个简单的Demo,使用两个Button,分别用来start & stop AsyncTask。

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View; public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "AsyncTaskTest";
private TestTask task = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); findViewById(R.id.btn1).setOnClickListener(this);//start async task btn
findViewById(R.id.btn2).setOnClickListener(this);//stop async task btn
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn1:
task = new TestTask();
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
break;
case R.id.btn2:
if (task != null && !task.isCancelled() && task.getStatus() == AsyncTask.Status.RUNNING) {
task.cancel(true);
task = null;
}
break;
}
} class TestTask extends AsyncTask<Void, Void, Void> { @Override
protected Void doInBackground(Void... params) {
int count = 5;
while (count > 0) {
count--;
if (isCancelled()) { //通过isCancelled()判断cancel(true)是否成功。
Log.d(TAG,"Cancel");
break;
}
Log.d(TAG,"Start Sleep");
try {
Thread.sleep(2000);//模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG,"End Sleep");
}
return null;
} @Override
protected void onPostExecute(Void aVoid) {
Log.d(TAG,"onPostExecute");
super.onPostExecute(aVoid);
} @Override
protected void onCancelled() {
Log.d(TAG,"onCancelled");
super.onCancelled();
}
} }

当然真实案例中,在doInBackground()函数中,不像Demo中只有一个简单的while()循环,所以可能需要多加几个isCancelled()来结束doInBackground()中的任务。

Android开发--取消AsyncTask的更多相关文章

  1. Android开发-取消程序标题栏或自定义标题栏

    注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在Android开发中,跟据需要我们有时候需要自定义应用程序的标题栏或者取消程序的标题栏,下面本菜鸟在此记录与分享一下自己使用的方法 ...

  2. Android开发之异步具体解释(二)之AsyncTask

    请尊重他人的劳动成果,转载请注明出处:Android开发之异步具体解释(二)之AsyncTask http://blog.csdn.net/fengyuzhengfan/article/details ...

  3. Android开发CheckBox控件,全选,反选,取消全选

    在Android开发中我们经常会使用CheckBox控件,那么怎么实现CheckBox控件的全选,反选呢 首先布局我们的界面: <?xml version="1.0" enc ...

  4. Android开发 ---基本UI组件3:单选按钮、多选按钮、下拉列表、提交按钮、重置按钮、取消按钮

    Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个用户注册按钮 <?xml version="1.0" encoding=&q ...

  5. Android线程之AsyncTask

    在之前的博客中为大家分享过关于Android多线程处理,想必大家对于Android为什么要使用多线程已经有了清晰的认识,我就在简单唠两句,Android规定UI界面的更新必须在在主线程进行,对于访问网 ...

  6. Android开发权威指南(第2版)新书发布

    <Android 开发权威指南(第二版)>是畅销书<Android开发权威指南>的升级版,内容更新超过80%,是一本全面介绍Android应用开发的专著,拥有45 章精彩内容供 ...

  7. android 开发如何做内存优化

    不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露.其实如果我 们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造 ...

  8. Android开发 |常见的内存泄漏问题及解决办法

    在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...

  9. 我的Android开发相关文章

    Pro Android学习笔记: Pro Android学习笔记(一零七):2D动画(2):layout渐变动画 2014.7.25 Pro Android学习笔记(一零六):2D动画(1):fram ...

随机推荐

  1. poj_3468 伸展树

    题目大意 一个数列,每次操作可以是将某区间数字都加上一个相同的整数,也可以是询问一个区间中所有数字的和.(这里区间指的是数列中连续的若干个数)对每次询问给出结果. 思路 1. 伸展树的一般规律 对于区 ...

  2. redis 之初体验(window)

    1 下载window版本的redis :https://github.com/MSOpenTech/redis/releases 2 解压压缩包.我的放在了E盘: E:/redis 3 程序,输入cm ...

  3. [分享]收集的Linux学习资源

    下面是我收集的一些Linux资源,与大家分享.大家共同学习,一起进步. 国内的专业Linux网站(GB) 1. ChinaUnix:http://www.chinaunix.net/ 2. Linux ...

  4. ios开发 点击文本(TextField)输入的时候向上推以及输入之后恢复的动画

    1.添加委托UITextFieldDelegate 2. -(BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resi ...

  5. java的Result类

    import org.apache.commons.lang.StringUtils; import java.io.Serializable;import java.util.HashMap;imp ...

  6. IDEA Tomcat部署时war和war exploded区别以及平时踩得坑

    war和war exploded的区别 在使用IDEA开发项目的时候,部署Tomcat的时候通常会出现下边的情况: 是选择war还是war exploded 这里首先看一下他们两个的区别: war模式 ...

  7. mysql表大小写问题

    查看大小写区分 mysql> show variables like "%case%"; linux在mysql安装完后默认:区分表名的大小写,不区分列名的大小写 改变表名的 ...

  8. Object 对象有哪些方法?

    这个不看还真不一定能说全,请养成良好的阅读源码和JDK文档的习惯. 总结一下:一共11个,wait的3个+notify的2个,hashCode和equals还有toString共3个,然后clone和 ...

  9. Ubbeditor的使用

    简单介绍: 作为一种放在客户端文本编辑器,此时不能支持将JS.Html代码直接发送给服务器,这样将会给服务器带来极大的危险,比如UMEditor(富文本编辑器),它的使用需要关闭服务器端的代码检查的, ...

  10. Create an Index

    db.collection.createIndex( { name: -1 } ) Indexes — MongoDB Manual https://docs.mongodb.com/manual/i ...