AsyncTask

转载 2016年08月31日 13:01:20

构建AsyncTask子类的泛型参数

AsyncTask <Params,Progress,Result>是一个抽象类,通常用于被继承

  • Params:启动任务时输入的参数类型
  • Progress:后台任务执行中返回进度值的类型
  • Result:后台任务执行完成后返回结果的类型

AsyncTask子类的回调方法主要有

  • doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成
  • onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作
  • onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法.通过此方法进行UI的更新
  • onProgressUpdate:当在doInBackground方法中调用publishProgress方法更新任务执行进度后,将调用此方法.通过此方法可以获取任务的完成进度

ImageActivity.java (加载网络图片)

import android.app.Activity;
import android.graphics.*;
import android.os.*;
import android.view.View;
import android.widget.*;
import java.io.*;
import java.net.*;

/**
 * Created by caobotao on 15/12/2.
 */
public class ImageActivity extends Activity {
    private ImageView imageView ;
    private ProgressBar progressBar ;
    private static String URL = "http://pic3.zhongsou.com/image/38063b6d7defc892894.jpg";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image);
        imageView = (ImageView) findViewById(R.id.image);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        //通过调用execute方法开始处理异步任务.相当于线程中的start方法.
        new MyAsyncTask().execute(URL);
    }

    class MyAsyncTask extends AsyncTask<String,Void,Bitmap> {

        //onPreExecute用于异步处理前的操作
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //此处将progressBar设置为可见.
            progressBar.setVisibility(View.VISIBLE);
        }

        //在doInBackground方法中进行异步任务的处理.
        @Override
        protected Bitmap doInBackground(String... params) {
            //获取传进来的参数
            String url = params[0];
            Bitmap bitmap = null;
            URLConnection connection ;
            InputStream is ;
            try {
                connection = new URL(url).openConnection();
                is = connection.getInputStream();
                //为了更清楚的看到加载图片的等待操作,将线程休眠3秒钟.
                Thread.sleep(3000);
                BufferedInputStream bis = new BufferedInputStream(is);
                //通过decodeStream方法解析输入流
                bitmap = BitmapFactory.decodeStream(bis);
                is.close();
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return bitmap;
        }

        //onPostExecute用于UI的更新.此方法的参数为doInBackground方法返回的值.
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //隐藏progressBar
            progressBar.setVisibility(View.GONE);
            //更新imageView
            imageView.setImageBitmap(bitmap);
        }
    }
}

需要在Activity的onPause()方法中将正在执行的task标记为cancel状态,在doInBackground方法中进行异步处理时判断是否是cancel状态来决定是否取消之前的task.

ProgressActivity.java

import android.app.Activity;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.widget.ProgressBar;

import java.util.Scanner;
/**
 * Created by caobotao on 15/12/2.
 */
public class ProgressActivity extends Activity{
    private ProgressBar progressBar;
    private MyAsyncTask myAsyncTask;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.progress);
        progressBar = (ProgressBar) findViewById(R.id.progress);
        myAsyncTask = new MyAsyncTask();
        //启动异步任务的处理
        myAsyncTask.execute();
    }

    //AsyncTask是基于线程池进行实现的,当一个线程没有结束时,后面的线程是不能执行的.
    @Override
    protected void onPause() {
        super.onPause();
        if (myAsyncTask != null && myAsyncTask.getStatus() == Status.RUNNING) {
            //cancel方法只是将对应的AsyncTask标记为cancelt状态,并不是真正的取消线程的执行.
            myAsyncTask.cancel(true);
        }
    }

    class MyAsyncTask extends AsyncTask<Void,Integer,Void>{
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            //通过publishProgress方法传过来的值进行进度条的更新.
            progressBar.setProgress(values[0]);
        }

        @Override
        protected Void doInBackground(Void... params) {
            //使用for循环来模拟进度条的进度.
            for (int i = 0;i < 100; i ++){
                //如果task是cancel状态,则终止for循环,以进行下个task的执行.
                if (isCancelled()){
                    break;
                }
                //调用publishProgress方法将自动触发onProgressUpdate方法来进行进度条的更新.
                publishProgress(i);
                try {
                    //通过线程休眠模拟耗时操作
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
}

.使用AsyncTask的注意事项

① 必须在UI线程中创建AsyncTask的实例.

② 只能在UI线程中调用AsyncTask的execute方法.

③ AsyncTask被重写的四个方法是系统自动调用的,不应手动调用.

④ 每个AsyncTask只能被执行(execute方法)一次,多次执行将会引发异常.

⑤ AsyncTask的四个方法,只有doInBackground方法是运行在其他线程中,其他三个方法都运行在UI线程中,也就说其他三个方法都可以进行UI的更新操作.

作者:caobotao
出处: http://www.cnblogs.com/caobotao/p/5020857.html

Android实现弱引用AsyncTask,将内存泄漏置之度外。

AsyncTask可谓是在Android中隐藏很深,曾经叱咤风云的功夫级人物。它的存在让网络和UI的通信变得异常简单和轻松。AsyncTask使用上的简单也得以让很多开发者青睐。一般情况下,Async...
  • u013718120
  • u013718120
  • 2016年11月04日 11:50
  • 2846

Android —— 静态AsyncTask解决内存泄漏

Android中我们经常需要开启子线程去获取网络数据,或者说做一些耗时操作,开发者经常使用的就是AsyncTask,Android 1.5提供的工具类AsyncTask使我们创建异步线程更加便捷。如果...
  • womengmengyan
  • womengmengyan
  • 2016年08月25日 18:53
  • 3510

Android之AsyncTask的内存泄露问题

AsyncTask是Android提供的一种用于异步处理数据的异步类,使用AsyncTask可以不用直接使用Thread和Handler来处理后台操作。AsyncTask被引入到Android中就被贴...
  • LoveYaozu
  • LoveYaozu
  • 2016年04月25日 22:41
  • 2809

一个例子谈谈AsyncTask的用法

Android前端复习
  • Kaiwii
  • Kaiwii
  • 2014年03月19日 16:51
  • 4004

取消AsyncTask

在执行AsyncTask程序的时候,调用cancel(true)有时会出现AsyncTask没有及时取消的情况,最有效的方法是在doInBackground方法里判断一下: ... @...
  • cuiweijie3
  • cuiweijie3
  • 2013年03月12日 15:43
  • 4714

AsyncTask你真的用对了吗?

在之前的文章深入探究了Handler,《从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)》我们知道了Android的消息机制主要靠H...
  • ly502541243
  • ly502541243
  • 2016年08月26日 16:40
  • 7581

AsyncTask优缺点(两种线程池)

AsyncTask两种线程池  http://bbs.51cto.com/thread-1114378-1.html (API 3.0以后): 1.THREAD_POOL_EXECUTOR, ...
  • ai_yong_jie
  • ai_yong_jie
  • 2016年08月04日 10:02
  • 2243

AsyncTask 使用和缺陷

一、AsyncTask的基本用法 由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它。在继承时我们可以为AsyncTask类指定三个泛型参数,这三个参数的用途如下:...
  • boyupeng
  • boyupeng
  • 2015年10月09日 17:06
  • 12015

AsyncTask多任务执行

通过上篇博客对AsyncTask源码进行分析之后,我们对AsyncTask
  • zkw12358
  • zkw12358
  • 2014年07月26日 16:01
  • 881

AsyncTask 内部类

AsyncTask这个类产生的Thread对象的生命周期是不确定的,是应用程序无法控制的,因此如果AsyncTask作为Activity的内部类,就更容易出现内存泄露的问题。这个问题的解决办法小马当时...
  • fuweiping
  • fuweiping
  • 2014年02月10日 10:03
  • 655
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AsyncTask
举报原因:
原因补充:

(最多只允许输入30个字)