Android开发--取消AsyncTask
在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的更多相关文章
- Android开发-取消程序标题栏或自定义标题栏
注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在Android开发中,跟据需要我们有时候需要自定义应用程序的标题栏或者取消程序的标题栏,下面本菜鸟在此记录与分享一下自己使用的方法 ...
- Android开发之异步具体解释(二)之AsyncTask
请尊重他人的劳动成果,转载请注明出处:Android开发之异步具体解释(二)之AsyncTask http://blog.csdn.net/fengyuzhengfan/article/details ...
- Android开发CheckBox控件,全选,反选,取消全选
在Android开发中我们经常会使用CheckBox控件,那么怎么实现CheckBox控件的全选,反选呢 首先布局我们的界面: <?xml version="1.0" enc ...
- Android开发 ---基本UI组件3:单选按钮、多选按钮、下拉列表、提交按钮、重置按钮、取消按钮
Android开发 ---基本UI组件2 1.activity_main.xml 描述: 定义一个用户注册按钮 <?xml version="1.0" encoding=&q ...
- Android线程之AsyncTask
在之前的博客中为大家分享过关于Android多线程处理,想必大家对于Android为什么要使用多线程已经有了清晰的认识,我就在简单唠两句,Android规定UI界面的更新必须在在主线程进行,对于访问网 ...
- Android开发权威指南(第2版)新书发布
<Android 开发权威指南(第二版)>是畅销书<Android开发权威指南>的升级版,内容更新超过80%,是一本全面介绍Android应用开发的专著,拥有45 章精彩内容供 ...
- android 开发如何做内存优化
不少人认为JAVA程序,因为有垃圾回收机制,应该没有内存泄露.其实如果我 们一个程序中,已经不再使用某个对象,但是因为仍然有引用指向它,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造 ...
- Android开发 |常见的内存泄漏问题及解决办法
在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要 ...
- 我的Android开发相关文章
Pro Android学习笔记: Pro Android学习笔记(一零七):2D动画(2):layout渐变动画 2014.7.25 Pro Android学习笔记(一零六):2D动画(1):fram ...
随机推荐
- php学习四:数组(一)
1. 直接赋值方式: ① 索引数组:以索引来存储数据,内存不是连续的,但是js中的内存是连续的 代码如下: $array[0] = "11"; $array[1] = &qu ...
- PHP遍历文件夹及子文件夹所有文件(此外还有飞递归的方法)
<html> <body> <?php function traverse($path = '.') { $current_dir = opendir($path); / ...
- String.Join重载String.Join 方法 (String, String[], Int32, Int32)
https://msdn.microsoft.com/zh-cn/library/tk0xe5h0 String.Join 方法 (String, String[], Int32, Int32) 官方 ...
- synchronized同步语句块
用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个长时间的任务,那么B线程则必须等待比较长时间.在这样的情况下可以使用synchronized同步语句块来解 ...
- saltstack之syndic的配置
author: headsen chen date: 2018-08-04 22:22:09 1,架构 2,配置 2.1,配置master: yum -y install epel-relea ...
- C++ 初始化函数的实现
http://www.cppblog.com/xlshcn/archive/2007/11/21/37088.aspx
- 【BZOJ1001】[BeiJing2006]狼抓兔子 对偶图最短路
[BZOJ1001][BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子 ...
- 【BZOJ1717】[Usaco2006 Dec]Milk Patterns 产奶的模式 后缀数组
[BZOJ1717][Usaco2006 Dec]Milk Patterns Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量 ...
- 批量远程执行linux服务器程序--基于pxpect(多进程、记日志版)
#!/usr/bin/python '''Created on 2015-06-09@author: Administrator''' import pexpect import os,sys fro ...
- MySQL命令行基本命令操作
进入命令模式后, 显示所有数据库 show databases; 选定某个数据库 use 数据库名; 创建数据库 create database 数据库名; 删除数据库 drop table 数据库名 ...