异步任务-AsyncTask

  • 为什么要使用异步任务

  1. android单线程模型
  2. 耗时操作放在非主线程执行
  • AsyncTask为何而生

  1. 子线程中更新ui
  2. 封装、简化异步操作
  • 构建AsyncTask子类的参数

AsyncTask<Params,Progress,Result>是一个抽象类。
通常用于被继承,继承AsyncTask需要指定如下三个泛型参数:

  • Params:启动任务时输入参数的类型。

  • Progress:后台任务执行中返回进度值的类型。

  • Result: 后台执行任务完成后返回结果的类型。

  • 构建AsyncTask子类的回调方法

  • doInBackground:必须重写,异步执行后台线程将要完成的任务

  • onPreExecute:执行后台耗时操作前被调用,通常用户完成一些初始化操作

  • onPostExcute:当doInBackground()完成后,系统会自动调用 onPostExcute(),并将doInBackground方法返回的值传给该方法

  • onProgressUpdate: 在doInBackground方法中调用publishProgress()方法更新任务的执行进度后,就会调用该方法。

  • AsyncTask注意事项

  • 必须在ui线程中创建AsyncTask的实例

  • 必须在ui线程中调用AsyncTask的execute()方法。

  • 重写的四个方法是系统自带调用的,不应受到调用

  • 每个AsyncTsk只能被执行一次,多次调用将会引发异常

  • AsyncTask模拟网络图片加载

package com.tyl.mystudy.asynctask;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import androidx.annotation.Nullable;
import com.tyl.mystudy.R;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
/**
 * Author tyl
 * Created  on 2020/2/6  12:52
 * Describe:模拟网络图片加载
 */
public class AsyncTaskActivity extends Activity {
    private ImageView iv_image;
    private ProgressBar pro_progress;
    private String imgUrl="https://www.imooc.com/static/img/index/logo.png";
    private MyAsyncTask myAsyncTask;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_asynctask);
        iv_image=findViewById(R.id.iv_image);
        pro_progress=findViewById(R.id.pro_progress);
        myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute(imgUrl);//将url作为参数传入
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (myAsyncTask!=null&&myAsyncTask.getStatus()== AsyncTask.Status.RUNNING){
            //asyncTask还在运行
            //cancel方法只是将对应的asyncTask标记为cancel状态并不是真正的取消线程的执行
            // 可以在doInBackground方法中通过isCancelled()方法判断是否已处于cancel如果true则手动结束后台任务
            myAsyncTask.cancel(true);
        }
    }
    public class MyAsyncTask extends AsyncTask<String,Integer, Bitmap> {
        /**
         * AsyncTask<Params,Progress,Result>是一个抽象类
         * Params:启动任务时输入参数的类型。
         * Progress:后台任务执行中返回进度值的类型
         * Result: 后台执行任务完成后返回结果的类型。
         *
         * 调用该AsyncTask方法:
         * MyAsyncTask myAsyncTask = new MyAsyncTask();
         * myAsyncTask.execute();
         * 调用后的代码执行顺序:
         *onPreExecute()-doInBackground()-onPostExecute()
         * onProgressUpdate()需要在doInBackground方法中调用publishProgress()方法更新任务的执行进度后,才会调用该方法。
         * */
        @Override
        protected Bitmap doInBackground(String... params) {
            //可以在这里执行一些异步任务 这里的所以执行都在子线程中
//            publishProgress();//可以传入值,并调用onProgressUpdate()
            if (!isCancelled()){
                String url=params[0];
                Bitmap bitmap=null;
                URLConnection connection;
                InputStream inputStream;
                try {
                    connection=new URL(url).openConnection();//获取网络连接对象
                    inputStream=connection.getInputStream();//获取到输入流
                    BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                    bitmap = BitmapFactory.decodeStream(bufferedInputStream);//将输入流解析成bitMap
                    inputStream.close();//关闭输入流
                    bufferedInputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //将bitmap作为返回值返回
                return bitmap;
            }
          return null;
        }
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //可以在这里执行一些代码初始化的工作
            iv_image.setVisibility(View.GONE);
            pro_progress.setVisibility(View.VISIBLE);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //在这里与ui线程通信 这个方法运行在主线程
            if (bitmap!=null){
                iv_image.setImageBitmap(bitmap);
                iv_image.setVisibility(View.VISIBLE);
                pro_progress.setVisibility(View.GONE);
            }
        }

        @Override
        protected void onProgressUpdate(Integer... integers) {
            super.onProgressUpdate(integers);
            //在这里执行进度更新
//            pro_progress.setProgress(integers[0]);
        }

    }
}

推荐阅读更多精彩内容

  • 引言:搞 Android 这么久了,一直没有主动去学习使用 AsyncTask ,现在应该很少有人在使用了,但面试...
    JustDo23阅读 137评论 0 1
  • 之前简单的介绍了Android-Handler的消息传递机制,其中计算质数的demo在利用子Handler去计算和...
    Mr_冯先生阅读 617评论 0 9
  • AsyncTask封装了Thread和Handler,是一种轻量级的异步任务类。 参数 Params:执行exec...
    Gentleman1995阅读 382评论 1 2
  • 什么是HTTP协议? HTTP是hypertext transport protocol的缩写,即超文本传输协议。...
    暖A暖阅读 37评论 0 3
  • 这周听了武志红的《关系即命运》,感觉自己有了很深的感悟。 武志红说:“关系:即命运。直观地理解就是,你遇见了谁?如...
    杨杨897阅读 71评论 0 0