Android AsyncTask详解

一、AsyncTask与Handler对比

在Android中实现异步任务机制有两种方式,Handler和AsyncTask。
Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制。
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 线程,并且在界面上展示给用户.
      * 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;
		}

	}
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值