一、AsyncTask与Handler对比
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
AsyncTask介绍
public abstract class AsyncTask<Params, Progress, Result> {
1)AsyncTaskd定义了三种泛型类型 Params,Progress,Result.
Params启动任务时传入的参数,比如网络请求Http的URL。
Progress后台任务执行进度百分比。
Result后台任务执行完毕返回的最终执行结果,可以是String等类型。
2) 实现AsyncTask中定义的下面一个或几个方法
* onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
* doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
* onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
* onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.
* onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
* doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
* onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
* onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.
* onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
在使用的时候,有几点需要格外注意:
1.异步任务的实例必须在UI线程中创建。
2.execute(Params... params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params... params)中更改UI组件的信息。
5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。
二)AsyncTask异步加载进度条SeekBar代码
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.scxh.android1503.R;
import com.scxh.android1503.util.Logs;
public class AsyncTaskActivity extends Activity implements OnClickListener{
private SeekBar mSeekBar;
private Button mStartDownLoadBtn,mAsyncTaskLoadBtn,mStopLoadBtn;
private TextView mShowMessageTxt;
private MyAsyncTask mAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.asynctask_download_layout);
mSeekBar = (SeekBar) findViewById(R.id.async_seekbar);
mStartDownLoadBtn = (Button) findViewById(R.id.async_start_btn);
mAsyncTaskLoadBtn = (Button) findViewById(R.id.async_load_btn);
mStopLoadBtn = (Button) findViewById(R.id.async_stop_btn);
mShowMessageTxt = (TextView) findViewById(R.id.async_show_message_txt);
mStartDownLoadBtn.setOnClickListener(this);
mAsyncTaskLoadBtn.setOnClickListener(this);
mStopLoadBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.async_start_btn:
new Thread(new Runnable() {
@Override
public void run() {
for(int i = 0; i < 100; i++){
mSeekBar.setProgress(i);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
break;
case R.id.async_load_btn:
String url = "http://www.baidu.com/mm.png";
String url1 = "http://www.baidu.com/mm1.png";
mAsyncTask = new MyAsyncTask();
mAsyncTask.execute(url,url1); /**默认排队执行异步任务, 每执行一次异步任务将被放任务队列*/
break;
case R.id.async_stop_btn:
Logs.v("mAsyncTask.isCancelled() :"+mAsyncTask.isCancelled());
if(!mAsyncTask.isCancelled()){
mAsyncTask.cancel(true); //停止异步任务
Logs.v("mAsyncTask.cancel(true); //停止异步任务");
}
break;
}
}
/**
* AsyncTask<String, Integer, String>
* Params 第一个参数: 传入异步任务中的数据类型
* Progress 第二个参数: 异步任务执行过程中发送数据类型
* Result 第三个参数: 异步任务执行完成后返回数据类型
*
* 注:如果类型为 Void 表示没有参数
*/
public class MyAsyncTask extends AsyncTask<String, Integer, String>{
/**
* 执行异步任务前调用方法
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
Logs.v("onPreExecute >>>>>> ");
}
/**
* 后台(子线程)执行异步任务
*/
@Override
protected String doInBackground(String... params) {
Logs.v("doInBackground >>>>>> ");
String url1 = params[0];
String url2 = params[1];
Logs.v("url1 : "+url1 + "\n url2 :"+url2 );
for(int i = 1; i <= 100; i++){
publishProgress(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String result = "下载成功";
return result;
}
/**
* 异步任务执行过程中调用方法.
* 必须在doInBackground方法中调用publishProgress()方法发送消息
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int progress = values[0];
Logs.v("onProgressUpdate >>>>>> "+progress);
mSeekBar.setProgress(progress);
mShowMessageTxt.setText(""+progress);
}
/**
* 异步任务执行完成后调用方法
*/
@Override
protected void onPostExecute(String result) {
Logs.v("onPostExecute >>>>>> ");
super.onPostExecute(result);
mShowMessageTxt.setText(result);
}
}
}
三)AsyncTask异步任务下载网络图片
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.http.HttpConnection;
import com.xhsc.layout.relativelayout.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Path;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
public class DownLoadAsyncActivity extends Activity implements OnClickListener {
GridView mGridview;
Button mButton;
Bitmap bitmap;
private Executor mExecutor;
String[] path = {
"http://img4.imgtn.bdimg.com/it/u=128811874,840272376&fm=21&gp=0.jpg",
"http://h.hiphotos.baidu.com/image/pic/item/48540923dd54564e854f5b30b1de9c82d1584f94.jpg",
"http://c.hiphotos.baidu.com/image/h%3D360/sign=624e1ab9be3eb1355bc7b1bd961fa8cb/7a899e510fb30f24a0e3da52ca95d143ad4b0361.jpg",
"http://c.hiphotos.baidu.com/image/h%3D360/sign=cca8acd1cc1b9d1695c79c67c3dfb4eb/bba1cd11728b4710037cc3c2c1cec3fdfc032368.jpg",
"http://h.hiphotos.baidu.com/image/h%3D360/sign=a2907fe8e51190ef1efb94d9fe1a9df7/3ac79f3df8dcd1009d045724708b4710b9122f1e.jpg",
"http://h.hiphotos.baidu.com/image/h%3D360/sign=b9b0c7669a510fb367197191e932c893/b999a9014c086e0642e8b69406087bf40bd1cba9.jpg",
"http://g.hiphotos.baidu.com/image/h%3D360/sign=649b9cce1c178a82d13c79a6c602737f/6c224f4a20a44623ef4ac3609a22720e0cf3d734.jpg",
"http://g.hiphotos.baidu.com/image/h%3D360/sign=caa2d267cfef7609230b9f991edca301/6d81800a19d8bc3e7763d030868ba61ea9d345e5.jpg",
"http://h.hiphotos.baidu.com/image/h%3D360/sign=efe4d20a249759ee555066cd82fb434e/0dd7912397dda1444a2adab5b0b7d0a20cf48692.jpg",
"http://g.hiphotos.baidu.com/image/h%3D360/sign=bf40c922952bd4075dc7d5fb4b889e9c/9f2f070828381f305f40daa3ab014c086e06f05b.jpg",
"http://d.hiphotos.baidu.com/image/h%3D360/sign=12d15e005b82b2b7b89f3fc201accb0a/d009b3de9c82d1587f2a9fb5820a19d8bc3e420e.jpg",
"http://b.hiphotos.baidu.com/image/h%3D360/sign=d215c4558444ebf872716239e9f8d736/37d12f2eb9389b50f6b71d048635e5dde7116e18.jpg",
"http://h.hiphotos.baidu.com/image/h%3D360/sign=92cf362a71f08202329297397bfafb8a/63d9f2d3572c11df96686d2a612762d0f703c27a.jpg",
"http://img5.imgtn.bdimg.com/it/u=3580210867,3098509580&fm=21&gp=0.jpg",
"http://e.hiphotos.baidu.com/image/h%3D360/sign=23d2cf38b08f8c54fcd3c3290a282dee/c9fcc3cec3fdfc031ec6ea6ed03f8794a5c226ad.jpg",
"http://img0.imgtn.bdimg.com/it/u=1070902365,2619384777&fm=21&gp=0.jpg",
"http://img1.imgtn.bdimg.com/it/u=2111648732,3690624201&fm=23&gp=0.jpg",
"http://img0.imgtn.bdimg.com/it/u=2081529157,1978722497&fm=23&gp=0.jpg",
"http://img5.imgtn.bdimg.com/it/u=2531484665,1615000788&fm=23&gp=0.jpg",
"http://img0.imgtn.bdimg.com/it/u=3135582527,842621827&fm=23&gp=0.jpg",
"http://img4.imgtn.bdimg.com/it/u=3756685971,1441134629&fm=23&gp=0.jpg",
"http://img0.imgtn.bdimg.com/it/u=3472918996,2339968434&fm=23&gp=0.jpg",
"http://img3.imgtn.bdimg.com/it/u=1050285812,2225196415&fm=23&gp=0.jpg" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.async_gridview_layout);
mButton = (Button) findViewById(R.id.async_download_btn);
mGridview = (GridView) findViewById(R.id.async_gridView);
mButton.setOnClickListener(this);
mExecutor = new ThreadPoolExecutor(10, 150, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
}
@Override
public void onClick(View v) {
/*MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute(path);*/
OptimalAdapter adapters = new OptimalAdapter(this);
mGridview.setAdapter(adapters);
adapters.setPath(path);
}
/**
*
* @param downLoadImage
* @return下载网络图片,返回个BitMap对象
*/
public Bitmap downLoadImage(String url) {
try {
Log.v("tag", ""+url+"\n");
URL urls = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urls.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
Log.v("tag", ""+bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
/**
*
* @author Optimal最优的意思,下载图片融入到适配器,只刷新一次getview方法
* 但缺点是图片错乱
*
*/
public class OptimalAdapter extends BaseAdapter{
LayoutInflater layoutInflater;
Context context;
String[] paths = new String[23];
public OptimalAdapter(Context context) {
this.context = context;
layoutInflater = LayoutInflater.from(context);
}
public void setPath(String[] path) {
this.paths = path;
notifyDataSetChanged();
}
@Override
public int getCount() {
return paths.length;
}
@Override
public Object getItem(int position) {
return paths[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageView;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.async_gridview_item_layout, null);
imageView = (ImageView) convertView.findViewById(R.id.async_item_imageview);
convertView.setTag(imageView);
} else {
imageView = (ImageView) convertView.getTag();
}
new AsyncTask<String, Void, Bitmap>() {
Bitmap bitmaps;
@Override
protected Bitmap doInBackground(String... params) {
bitmaps = downLoadImage(params[0]);
return bitmaps;
}
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
};
// }.execute(paths[position]);//单任务一个一个执行
}.executeOnExecutor(mExecutor, paths[position]);//多线程池同时运行多个线程
return convertView;
}
}
/**
*
* @author GidviewAdapter MyAsyncTask
* 虽是一次性赋值,
*
*/
public class GidviewAdapter extends BaseAdapter {
private ArrayList<Bitmap> images = new ArrayList<Bitmap>();
private Context context;
LayoutInflater layouInflater;
public GidviewAdapter(Context context) {
this.context = context;
layouInflater = LayoutInflater.from(context);
}
public void setImages(ArrayList<Bitmap> images) {
this.images = images;
notifyDataSetChanged();
}
@Override
public int getCount() {
return images.size();
}
@Override
public Object getItem(int position) {
return images.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
convertView = layouInflater.inflate(R.layout.async_gridview_item_layout, null);
imageView = (ImageView) convertView.findViewById(R.id.async_item_imageview);
convertView.setTag(imageView);
} else {
imageView = (ImageView) convertView.getTag();
}
imageView.setImageBitmap(images.get(position));
return convertView;
}
}
public class MyAsyncTask extends AsyncTask<String[], Void, ArrayList<Bitmap>> {
@Override
protected ArrayList<Bitmap> doInBackground(String[]... params) {
String[] paths = new String[9];
paths = params[0];
ArrayList<Bitmap> bitArrayList = new ArrayList<Bitmap>();
for (int i = 0; i < paths.length; i++) {
Log.v("tag", "paths[i]:"+paths[i]+"\n");
Log.v("tag", "doInBackground加载资源"+downLoadImage(paths[i]));
bitArrayList.add(downLoadImage(paths[i]));
}
return bitArrayList;
}
@Override
protected void onPostExecute(ArrayList<Bitmap> result) {
super.onPostExecute(result);
GidviewAdapter adapter = new GidviewAdapter(DownLoadAsyncActivity.this);
Log.v("tag", "onPostExecute设置数据源");
mGridview.setAdapter(adapter);
adapter.setImages(result);
}
}
/**
* 通过在异步任务中循环加载图片,不但刷新适配器实现
* 不提倡,原因:
* 1.重复刷新适配器执行getView方法
* 2.不能实现图片同步加载,相当于当线程执行.
*/
public void loadPictureByPublishProgress(){
new AsyncTask<String, Bitmap, Void>() {
@Override
protected Void doInBackground(String... params) {
for (int i = 0; i < params.length; i++) {
Bitmap bm = downLoadImage(params[i]);
publishProgress(bm);
}
return null;
}
protected void onProgressUpdate(Bitmap... values) {
// mAdapter.addDate(values[0]);
}
}.execute(path);
}
public class MyGridViewAdapter extends BaseAdapter {
private ArrayList<Bitmap> list = new ArrayList<Bitmap>();
private LayoutInflater infalter;
public void addDate(Bitmap bm) {
list.add(bm);
notifyDataSetChanged();
}
public MyGridViewAdapter(Context context) {
infalter = LayoutInflater.from(context);
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ImageView imageview;
if (convertView == null) {
convertView = infalter.inflate(R.layout.async_gridview_item_layout, null);
imageview = (ImageView) convertView.findViewById(R.id.async_item_imageview);
convertView.setTag(imageview);
} else {
imageview = (ImageView) convertView.getTag();
}
Bitmap bitmap = (Bitmap) getItem(position);
imageview.setImageBitmap(bitmap);
return convertView;
}
}
}