- 构建AsyncTask子类参数
- 因为他是一个抽象类所有继承他之后需要重写下面三个泛型参数
- Params:启动任务时,输入参数的类型。
- Progress:后台任务执行中返回进度值的类型
- Result:后台执行任务完成后返回结果的类型
- 因为他是一个抽象类所有继承他之后需要重写下面三个泛型参数
- 构建AsyncTask子类的回调方法
- dolnBackground:必须重写,异步执行后台程序将要完成的任务。
- onPreExecute:执行后台耗时操作前被调用,用户通常会做一些准备工作,如一些初始化的操作。
- onPostExecute():当dolnBackground()完成后,系统会自动调用该方法,并将dolnBackground()方法的返回值传给该方法。顾名思义就是展示我们所处理完的一个结果。
- onProgressUpdate():在dolnBackground()方法中调用publishProgress()方法更新任务就会触发该方法。
- 程序的调动顺序是:
- onPreExecute——>dolnBackground——>onPostExecute(没有调用publishProgress ())
- 传递进度:在dolnBackground()中调用publishProgress()方法的时候,就可以将一个进度值作为一参数传给onProgressUpdate(),我们就可以在onProgressUpdate()中得到这个参数,从而应用于更新一个异步进程的完成进度。
实例:
- 下载图片,并且显示(只是下载到缓存中。程序kill后需要再次下载)
- package com.example.administrator.android_asynctask;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by Administrator on 2016/5/26.
*/
public class ImageTestextends Activity {
private ImageView imageView;
private ProgressBar progressBar;
private static String URL = "http://img4.duitang.com/uploads/item/201308/10/20130810135200_tyE55.jpeg";
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image);
imageView = (ImageView) findViewById(R.id.imageView1);
progressBar = (ProgressBar) findViewById(R.id.pb);
new MyAsyncTask_1().execute(URL);
}
class MyAsyncTask_1 extends AsyncTask<String, Void, Bitmap> {
@Override
//在doInBackground启动前 ,显示progressBar
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
//隐藏progressBar
progressBar.setVisibility(View.GONE);
//传递bimap
imageView.setImageBitmap(bitmap);
Log.d("xyx","onPostExecute_bitmap=" + bitmap);
}
@Override
//参数是可变长数组
//<URL类型,进度值类型,返回值类型>
//doInBackground方法是开启一个异步线程做耗时操作的
protected Bitmap doInBackground(String... params) {
//取出对应的URL
String url = params[0];
Bitmap bitmap = null;
Log.d("xyx","url=" + url);
//定义网络链接对象
//以前的
// URLConnection connection;
HttpURLConnection connection;
//用于获取的数据的输入流
InputStream inputStream = null;
try {
//通过openConnection方法获取connection对象,获取网络连接对象
Thread.sleep(3000);
//原来方法
// connection = new URL(url).openConnection();
connection = (HttpURLConnection) new URL(url).openConnection();
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
//获取一个输入流
inputStream = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
//通过,decodeStream解析输入流流
bitmap = BitmapFactory.decodeStream(bis);
inputStream.close();
bis.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return bitmap;
}
}
}
- package com.example.administrator.android_asynctask;
- 模拟进度条
- package com.example.administrator.android_asynctask;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.List;
/**
* Created by Administrator on 2016/5/27.
*/
public class progressBarTest extends Activity {
private ProgressBar pb;
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.progress);
pb= (ProgressBar) findViewById(R.id.pb2);
new MyAsyncTask_ProgressBar().execute();
}
class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i <=100; i++) {
try {
Thread.sleep(300);
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
pb.setProgress(values[0]);
}
}
}
- package com.example.administrator.android_asynctask;
- 取消AsyncTask
-
- AsyncTask机制:因为他的底层是线程池 ,所有多次开始——返回后,他会卡住只有等之前的Task全部完成后,才会开始新的Task,而且,我们doInBackground中用的是for循环,所以只有等for循环结束,才会去执行下一个Task;所以会造成,多次进入后,进度条就会卡住的BUG,如何解决呢?
- 方案:
-
- AsyncTask和Activaty的生命周期保持一致,也就是Activity生命周期走到onPause的时候,把AsyncTask干掉就好了。
-
package com.example.administrator.android_asynctask; import android.app.Activity; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.ProgressBar; import android.widget.TextView; import java.util.List; /** * Created by Administrator on 2016/5/27. */ public class progressBarTest extends Activity { private ProgressBar pb; private TextView tv; private MyAsyncTask MTP; MyAsyncTask_ProgressBar mb = new MyAsyncTask_ProgressBar(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.progress); pb = (ProgressBar) findViewById(R.id.pb2); mb.execute(); } protected void onPause() { super.onPause(); if ((mb != null) && (mb.getStatus() == AsyncTask.Status.RUNNING)) { //这只是把MTP标记为cancel状态,不是真正的取消了线程,那我就需要, // 给doInBackground中的for循环设定判断条件, // 并且给onProgressUpdate进行判断是否要更新 mb.cancel(true); } } class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> { @Override protected Void doInBackground(Void... params) { for (int i = 0; i <= 100; i++) { //是否有cancel状态 if (isCancelled()) { break; } try { Thread.sleep(300); publishProgress(i); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if (isCancelled()) { return; } pb.setProgress(values[0]); } } }
失败原因:
- 下载部分:
- 内部类是要放在外部类里面的
- 图片无法显示的原因:bitmap通过bitmap = BitmapFactory.decodeStream(bis);这方法无法获得bitmap值;
- 解决办法,网址有问题,不是图片网址
- 附带博客一个,解决其他问题:http://blog.youkuaiyun.com/andypan1314/article/details/6670320
总结:
- 必须在UI线程中创建AsyncTask的实例
- 必须在UI线程中调用AsyncTask的execute()方法
- 重写的四个方法是系统自动调用的,不应手动调用
- 每个AsyncTask只能被执行一次,多次调用将会引发异常
- dolnBackground只有这方法是在其他线程的,其他方法都是在UI线程。