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

  前面说了如何操作AsyncTask,这篇我们来说一下如何关闭AsyncTask。

  有人就问了:为什么要关闭AsyncTask呢?很简单,AsyncTask 是在后台执行耗时操作(获取数据),当你离开当前页面或者结束进程时,也就是跳到你另一个页面不需要当前页面的数据。如果不关闭,其它页面无法显示数据,因为后台还在获取当前页面的数据,也可理解为堵塞。

  现在我们再运行一下上一篇博客里的app:

我们点击Back后再次进入App,点击产看数据

  我们会发现,再次点击时,数据没有立刻加载,而是过了一会才加载。有人会讲是网络问题,但我们是模拟的数据加载,没有经过网络。

  这就是上面所讲的堵塞。AsyncTask在执行多个线程时,是单个执行,其它线程是在缓冲区。当执行一个下一个才开始(One by one)

  那么怎么关闭呢?

  通过api,我们会发现一个 AsyncTask.cancel(true);

  A task can be cancelled at any time by invoking cancel(boolean). Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)

  意思是: 

  • 我们可以随时调用 cancel(boolean)去取消这个加载任务,调用这个方法会间接调用 iscancelled 并且返回true 。
  • 调用cancel()后,在doInBackground()return后 我们将会调用onCancelled(Object) 不在调用onPostExecute(Object)
  • 为了保证任务更快取消掉,你应该在doInBackground()周期性的检查iscancelled 去进行判断。

 现在我们就在MainActivity中的onPause(退出时)写入代码

 @Override
    protected void onPause() {
        //如果异步任务不为空 并且状态是 运行时  ,就把他取消这个加载任务
        if(task !=null && task.getStatus() == AsyncTask.Status.RUNNING){
            task.cancel(true);

        }
        super.onPause();
    }

再在AsyncTask 中加上 红色 代码,判断

public class MyTask extends AsyncTask{
    private List<User> userlist;
    private BaseAdapter adapter;
    private MainActivity activity;
    private String barNum;
    public MyTask(MainActivity activity) {
        this.activity = activity;
    }

    @Override
    protected Object doInBackground(Object... params) {
        userlist = (List<User>) params[0];
        adapter = (BaseAdapter) params[1];
        for(int i=1 ;i<=100;i++){
            if(isCancelled()){
                break;
            }
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            userlist.add(new User("zhangsan"+i,18+i,"aa"+i+"aa"));
            publishProgress(i);
            barNum = i+"%";
        }
        return userlist;
    }
    @Override
    protected void onProgressUpdate(Object... values) {
        if(isCancelled()){
            return;
        }
        Button btn = (Button) activity.findViewById(R.id.button1);
        btn.setVisibility(View.GONE);
        TextView num = (TextView) activity.findViewById(R.id.barNum);
        int bar = Integer.parseInt(values[0].toString());
        /*bar = (bar)*25;*/
        ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.seekBar1);
        progressBar.setProgress(bar);
        num.setText(barNum);
        //progressBar.setBackgroundColor(activity.getResources().getColor(R.color.orange));
        /*progressBar.setBackgroundResource(R.color.orange);*/
        adapter.notifyDataSetChanged();
    }

}

  这时,当我Back后再点进来加载,立马就开始了。有人会觉得疑惑:我在退出前不是cancel 了吗?为什么还要在异步任务中进行分步判断。

  当在onPause中 cancel 掉,取消了这个异步加载,但是在AsyncTask 中的isCanceled 值是一直没变,默认false , 即不关闭。

  

谢谢大家的关注。 I am big!It‘s the picture that got small.    ---- 我是巨大的!是那些照片让我变得渺小了。(《日落大道》)  

时间: 2024-10-20 20:12:25

Android -- 关闭AsyncTask(异步任务)的相关文章

Android 利用 AsyncTask 异步读取网络图片

1.新建Android工程AsyncLoadPicture 新建布局文件activity_main.xml主界面为一个GridView,还有其布局文件gridview_item.xml 2.功能主界面MainActivity.java,主代码如下 1 package com.example.asyncloadpicture; 2 3 import java.util.ArrayList; 4 5 import android.app.Activity; 6 import android.cont

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

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

Android多线程分析之五:使用AsyncTask异步下载图像

Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<Android多线程分析之中的一个:使用Thread异步下载图像>中.曾演示了怎样使用 Thread 来完毕异步任务. Android 为了简化在 UI 线程中完毕异步任务(毕竟 UI 线程是 app 最重要的线程).实现了一个名为 AysncTask 的模板类.使用 AysncTask 能够在异步任务进行的同

Android --AsyncTask异步任务(一)

1.为什么要异步任务 Android单线程模式 耗时操作放在非主线程(UI线程)中执行 我们都知道Android是单线程模式,只有主线程才能对UI操作,简称UI线程.当然这样的好处是:保证UI的稳定性.准确性,避免多线程同时对UI的操作,导致UI的混乱 但同时Android是一个多线程的操作系统,不可能把全部的事情放在主线程.如果任务堵塞,当时间过长,会抛出ANR(Application Not Responding)错误. 2.AsyncTask为何而生 子线程中更新UI 封装.简化异步操作

Android AsyncTask异步任务

在上一篇文章<Android网络编程之使用HttpClient进行Get方式通信>中,我们强制直接在UI线程进行网络操作,在实际的应用开发过程中不能这样做,因为这样很可能会阻塞UI,影响用户体验.为了避免直接在UI线程中进行网络操作,我们可以使用AsyncTask异步处理网络通信和UI更新.通过AysncTask可以很容易的启动后台线程进行网络通信,然后将结果返回到UI线程中. AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接

Android异步更新UI的方式之使用AsyncTask异步任务

由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中更新UI,给大家介绍一种方式:使用AsyncTask异步任务. 下面用这种方式更新一个TextView: 注:更新UI的操作只能在onPostExecute(String result)方法中. package com.example.runonuithreadtest;  import android.app.Activity;  import android.os.AsyncTask;  import android.

Android开发之异步详解(二)之AsyncTask

请尊重他人的劳动成果,转载请注明出处:Android开发之异步详解(二)之AsyncTask http://blog.csdn.net/fengyuzhengfan/article/details/40212745 我曾在<Android开发之异步详解(一)之Thread+Handler>一文中介绍过通过Thread+Handler实现异步操作.感兴趣的朋友可以看一下. 虽然Thread+Handler可以实现更新主线程的UI并实现异步,但Thread+Handler模式需要为每一个任务创建一

Android中使用Thread线程与AsyncTask异步任务的区别

最近和几个朋友交流Android开发中的网络下载问题时,谈到了用Thread开启下载线程时会产生的Bug,其实直接用子线程开启下载任务的确是很Low的做法,那么原因究竟如何,而比较高大上的做法是怎样?于是用这篇博文详细分析记录一下. 一.概念介绍 Thread是指在CPU运行的一个程序中,可以有多个执行路径.运行的程序称作进程,而这个执行路径,就被称为线程(如果对这两个名词不太理解的同学可以参考一下操作系统方面的书籍).Java中的多线程是指多个Thread可以在一段内同步执行,这样可以提高代码

Android AsyncTask异步加载WebAPI

之前做的程序一直存在很多问题,因为需要加载的Activity需要从网络加载数据.并没有完全正确的使用异步的方法去加载! 之前用的虽然是AsyncTask,但是在加载完成的时候还是并没有使用AsyncTask内置的方法去处理.而已傻傻的在OnCreate中处理.结果还是要等待AsyncTask加载完成后,等待OnCreate执行完成后,才load到Activity.这样子给人的第一感觉就是卡机了一样! 果断重新再写,这次的代码真是大换血.首先还是选择把带分页ListView进行封装了一下. 1 i