• ###为什么要使用异步任务
  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模拟网络图片加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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]);
}

}
}