AsyncTask.cancel()的结束问题

实际项目中有这么一个问题,用户进入详情界面,那么我们就要网络加载数据并展现在UI上,这个加载用线程或者异步。

这里就拿项目中统一用异步任务来获取网络数据把。

用户可能会有这么一个操作,它在一个商品(说说等)列表中,点击一个列表项,进入到相应的详情界面,这时候,我们会开启一个异步任务来获取网络数据,但是网络差的情况下, 用户可能就不愿意等了,立马按后退按钮回到列表,点击下一个别的列表项进入详情界面,发现加载太慢,又按后退键,如此反复,那么就导致此时有多个异步任务在执行,或者出现OOM问题,或者出现异步任务等待问题。

那么,作为开发者,我们对应的解决方案,便是在用户在详情界面按退出按钮退回到上一个界面的时候,把没有执行完的异步任务给结束掉。

------------------------------------------------------------------------------------------------------------------------------

现在我们发现了这个问题,又有了解决方案。那么就用代码来实现了。

那么 取消异步任务怎么做?

我一开始这样做,AsyncTask.cancel(true);

看下参数的定义:

@param mayInterruptIfRunning <tt>true</tt> if the thread executing this
     *        task should be interrupted; otherwise, in-progress tasks are allowed
     *        to complete.

1、如果是true,如果线程执行,则会被打断

2、如果是false,线程将会被运行执行完成

看到这,很显然,我们以为.cancel(true)就会结束掉我们开启的正在执行的异步任务

但是实际上并没有结束掉我们想要结束的异步任务~~

看了些别人对此的解释:

AsyncTask不会不考虑结果而直接结束一个线程。调用cancel()其实是给AsyncTask设置一个"canceled"状态。这取决于你去检查AsyncTask是否已经取消,之后决定是否终止你的操作。对于mayInterruptIfRunning——它所作的只是向运行中的线程发出interrupt()调用。在这种情况下,你的线程是不可中断的,也就不会终止该线程。

那么该如何结束线程呢?

可见.cancel()是给AsyncTask设置一个"canceled"的状态,那么想要终止异步任务,就需要在异步任务当中结束。

@Override
public void onProgressUpdate(Integer... value) {
// 判断是否被取消
if(isCancelled()) return;
.........
}

@Override
protected Integer doInBackground(Void... mgs) {
// Task被取消了,马上退出
if(isCancelled()) return null;
.......
// Task被取消了,马上退出

if(isCancelled()) return null;
}
...

另外结束异步任务的条件:

if(loadAsyncVedio!=null && !loadAsyncVedio.isCancelled()
                    && loadAsyncVedio.getStatus() == AsyncTask.Status.RUNNING){
                loadAsyncVedio.cancel(true);
                loadAsyncVedio = null;
            }
loadAsyncVedio(异步任务)

如此,便可以有效及时的结束异步任务

时间: 2024-10-26 12:46:13

AsyncTask.cancel()的结束问题的相关文章

AsyncTask(异步通信)

先new一个class继承AsyncTask类,AsyncTask要求提供三个泛型参数(Params .Progress .Result )其中,Params 为启动任务执行的输入参数,比如HTTP请求的URL:Progress 为后台任务执行的百分比:Result 后台执行任务最终返回的结果,比如String:然后AsyncTask的几个方法重写onPreExecute().doInBackground().onPostExecute().onProgressUpdate(),其中doInBa

Android -- 关闭AsyncTask(异步任务)

前面说了如何操作AsyncTask,这篇我们来说一下如何关闭AsyncTask. 有人就问了:为什么要关闭AsyncTask呢?很简单,AsyncTask 是在后台执行耗时操作(获取数据),当你离开当前页面或者结束进程时,也就是跳到你另一个页面不需要当前页面的数据.如果不关闭,其它页面无法显示数据,因为后台还在获取当前页面的数据,也可理解为堵塞. 现在我们再运行一下上一篇博客里的app: 我们点击Back后再次进入App,点击产看数据 我们会发现,再次点击时,数据没有立刻加载,而是过了一会才加载

AsyncTask实现多线程断点续传

前面一篇博客<AsyncTask实现断点续传>讲解了如何实现单线程下的断点续传,也就是一个文件只有一个线程进行下载.   对于大文件而言,使用多线程下载就会比单线程下载要快一些.多线程下载相比单线程下载要稍微复杂一点,本博文将详细讲解如何使用AsyncTask来实现多线程的断点续传下载. 一.实现原理 多线程下载首先要通过每个文件总的下载线程数(我这里设定5个)来确定每个线程所负责下载的起止位置. long blockLength = mFileLength / DEFAULT_POOL_SI

异步线程之AsyncTask

1.使用新线程的原因: android的UI线程主要负责处理用户的按键事件.用户触屏事件及屏幕绘图事件,因此其它其它操作不应该.也不能阻止UI线程,否则UI界面将会变得停止响应. 2.解决新线程不能更新UI组件的问题 2.1.使用Handler实现线程通信 2.2.Activity.runOnUiThread(Runnable) 2.3.View.post(Runnable) 2.4.View.postDelayed(Runnable) 2.5.AsyncTask 3.AsyncTask的使用:

Android线程管理之AsyncTask异步任务(四)

前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 产生背景: 我们都知道Android应用程序是单线程模型,在子线程无法直接操作UI主线程,必须通过Handler机制,想了解这方面的知识可以参考这篇文章:Android消息传递之Handler消息机制(一),所以基于这种考虑所以我们一般情况会采用Thread+Handler来处理比较耗时的操作,但是我们都知道

HandlerThread应用(对比AsyncTask)

之前说过HandlerThread的原理:: Handler机制的分发中心就在Looper中的loop(),HandlerThread将loop转到子线程中处理,降低了主线程的压力,使主界面更流畅 其实说白了,创建HandlerThread,只是为了用此线程的looper  最终的runnable都还是post到主线程运行(已用Toast测试过) 最终的最终就是降低了Loop中的loop功耗,依旧在主线程中运行. 这里我以Launcher2的代码来说说HandlerThread的具体应用:: /

Android异步任务AsyncTask的使用与原理分析

在上一篇文章<Android缓存机制&一个缓存框架推荐>中说到,在了解了Android缓存机制后我准备自己动手写一个LruCache和DiskLruCache二级缓存的轻量级的图片请求框架,在思考如何搭建这个框架时,纠结于用何种方式去下载图片,是直接new出一个线程呢,还是用看起来稍微高大上档次一点的AsyncTask异步任务来处理?思来想去,还是虚荣心作怪,还是用AsyncTask吧,正好这个工具类我之前用的也比较少,对它的原理也不是很清楚,趁这个机会,好好学一下AsyncTask的

Android内存泄漏的本质原因、解决办法、操作实例

今年最后一个迭代终于结束了,把过程中碰到的不熟悉的东西拉出来学习总结一下 内存泄漏的本质是:[一个(巨大的)短生命周期对象的引用被一个长生命周期(异步生命周期)的对象持有] 这个东西分为两个部分 获得一个(巨大的)短生命周期的对象 这个[巨大的短生命周期的对象]在Android中最有可能的就是[Activity]了 最容易无意识获得它的方式就是[非静态内部类隐式自动持有外部类的强引用] 把这个对象赋值给了一个长生命周期的对象 这个有一些常见的套路 套路一:直接赋值给了一个类的静态成员 这个静态成

Android BadTokenException 问题解决

前言 今天测试过程中发现了"android.view.WindowManager$BadTokenException"问题,这里记录一下解决方法.(PS:第一款应用上线了,感觉BUG还是比较多,感觉因为这个应用,能不能过试用期都是问题了,只能坚持加油了). 问题分析 这种问题其实在错误日志中都能给出很好的提示,下面贴一下部分有用的错误日志,如下所示: android.view.WindowManager$BadTokenException,ViewRootImpl.java,andro