1、主线程操作UI,耗时操作则在非主线程中执行
AsyncTask:子线程中更新UI;封装、简化异步操作
2、构建AsyncTask子类参数:
AsyncTask<Params,Progress,Result>是一个抽象类,通常用于被继承,继承AsyncTask需要指定如下三个泛型参数:
params:启动任务时候输入的参数类型
Progress:后台任务执行中返回进度值得类型
Result:后台执行任务完成后返回的结果的类型
3、构建AsyncTask子类的回调方法:
通常指定如下的方法:
doInBackground:必须重写,异步执行后台线程将要完成的任务
onPreExecute:执行后台耗时操作前被调用,通常用户完成一些初始化操作
onPostExecute:当doInBackground()完成后,系统会自动调用,即:展示我们异步线程完成的结果
onProgressUpdate:在doInBackground()方法中调用publishProgress()方法更新任务的执行进度后,就会触发该方法
4、操作AsynckTask的简单实例
首先新建类MyAsyncTask异步加载类
package com.example.administrator.asynctaskdemo;
import android.os.AsyncTask;
import android.util.Log;
/**
* 异步线程简单实例
* 三参数:
* @params 调用前传入参数
* @progress 后台调用中返回值得类型
* @result 后台执行完成后返回结果展示
*四方法
* doInBackground 必需有的执行方法
* onPreExecute :执行后台调用之前的操作,通常完成一些数据的初始化
* onPosExecute: 当doInBackground方法执行过后,系统自动调用,即展示异步线程完成的结果
* onProgressUpDate: 当执行后台方法doInbackground()时调用publishProgress()更新任务的执行进度,会触发该方法
*/
public class MyAsyncTask extends AsyncTask<Void,Void,Void> {
@Override
protected Void doInBackground(Void... voids) {
Log.i("AsyncTack","doInBackground");
publishProgress();//如果这个方法里面有参数,将传递给onProgressUpdate()方法
return null;
}
/**
* 调用异步执行方法前的初始化方法
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("AsyncTack","onPreExecute");
}
/**
* 异步完成后,系统自动调用展示异步线程结构
* @param aVoid 异步线程执行完毕后,携带的需要传递的参数值
*/
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Log.i("AsyncTask","onPostExecute");
}
/**
*当doInBackground()方法执行中调用publishProgress()更新任务执行的进度后,通过onProgressUpdate()方法展示
* @param values publishProgress()传递过来需要跟新的任务执行进度
*/
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
Log.i("AsyncTask","onProgressUpdate");
}
}
在activity中实例化调用
//1、实例化异步方法
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();//相当于线程中的.start
二、异步线程加载图片(获取网络数据流)
String url = params[0]//应为DoInBackground()方法后面跟的是不定长的数组,所以这里只需要取数组长度的第一位0即可
Bitmap bitmap = null;//接收类型初始化
URLConnection connection;//定义网络连接对象
InputStream is;//用于获取数据的输入流
try{
connection = new URL(url).openConnection;//获取网络连接
is=connection.getInputStream();//获取数据流
BufferedInpuutStream bis = new BufferedInputStream(is);//包装获取的数据流
Bitmap = BitmapFactory.decodeStream(bis);//将输入流解析成bitmap
is.close();//关闭输入流
bis.close();//关闭解析流
}catch (IOException e) {
e.printStackTrace();
}
这里有个问题不明白,为什么关闭获取输入流以后还要关闭BufferedInputStream包装数据流呢?一直想不明白
Thread.sleep(3000);//休眠3秒
doInBackground(String... strings)括号里面是不定长度的数据,这点需要注意
三、1、异步加载 模拟进度更新
class MyAsyncTackProgress extends AsyncTask<Void ,Integer,Void>{
@Override
protected Void doInBackground(Void... voids) {
//模拟进度更新
for (int i=0;i<100;i++){
publishProgress(i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
protected void onProgressUpdate(Integer...values){
super.onProgressUpdate(values);
//获取进度更新
}
}
三、2、因为异步加载方法调用底层线程池,但返回界面时,进程并未停止,所以需要在activity的生命周期的onPause方法中取消线程
/**
* another activity comes in front of the activity
*/
@Override
protected void onPause() {
super.onPause();
//对异步线程进行判断
if (mTaskProgress != null &&mTaskProgress.getStatus()==AsyncTask.Status.RUNNING){
//cancle只是将方法标记为取消状态,并不是真的取消了线程执行,需要调用isCancelled()
mTaskProgress.cancel(true);
}
}
这里有一个需要注意,尤其是对新手来说,mTaskProgress.cancel(true),只要写这个方法了,就可以直接与isCancelled()是否等于true,
protected Void doInBackground(Void... voids) {
//模拟进度更新
for (int i=0;i<100;i++){
if (isCancelled()){
break;
}
publishProgress(i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
protected void onProgressUpdate(Integer...values){
super.onProgressUpdate(values);
//获取进度更新
if (isCancelled()) {
return;
}
}
这里需要注意,doinbackgroud(),isCancelled()判断,直接用break;而onProgressUpdate()则是用的return;
四、参考代码demo,https://download.youkuaiyun.com/download/cryeye123/10562065