-
为什么要使用异步任务
- android单线程模型
- 耗时操作放在非主线程执行
-
AsyncTask为何而生
- 子线程中更新ui
- 封装、简化异步操作
-
构建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]);
}
}
}
网友评论