Android 简单的封装,可以更高效——AsyncTask

之前封装过很多工具类,一直没有整理,结果回过头要用的时候往往找起来很麻烦。一直想整理一下,结果不是没时间就是懒,不是懒就是没时间。今天群里有人问到AsyncTask,于是乎,我冒出个想法。封装一下AsyncTask,也方便我以后的使用。以前都没有图,今天没图怎么行呢,据说上图能提升某格。所以我也上图,而且是好图,多年珍藏的好图。

先简单介绍一下AsyncTask。

AsyncTask有三个泛型AsyncTask<Params, Progress, Result>,三种泛型分别代表“启动任务执行时的参数”、“任务执行的进度”、“任务执行的结果类型”。在很多时候,并不是所有类型都被使用,如果没有被使用,可以用Void类型代替。我通常的用法是AsyncTask<Void, Void, Result>,恨不得返回类型也是Void。可惜,人生无奈之事十有八九,此为其一。。

一个异步任务的执行一般包括以下几个步骤:
1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
在使用的时候,有几点需要格外注意:
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的执行过程,下面的代码就小kiss啦。

封装好的AsyncLoader类。

import android.os.AsyncTask;


/**
 * 
 * @Description:异步数据加载器
 * <p>创建日期:2013-9-3 </p>
 * @version V1.0  
 * @author LZP
 * @see
 */
public class AsyncLoader<P, S, T> extends AsyncTask<P, S, T> {

	private OnLoadListener<P, S, T> mListener;
	private int mDataType;
	private Exception ex;

	public AsyncLoader(int dataType) {
		mDataType = dataType;

		mListener = new OnLoadListener<P, S, T>() {
			@Override
			public void onDataStart() {
			}

			@Override
			public T doInWorkerThread(int dataType, P... params)
					throws Exception {
				return null;
			}
			
			@Override
			public void onDataGet(T result) {
			}

			@Override
			public void onDataFail(Exception e) {
			}

			@Override
			public void onDataFinish() {
			}

			@Override
			public void onDataProgress(S... values) {
			}
			
		};
	}

	public void setOnLoadListener(OnLoadListener<P, S, T> listener) {
		if (listener != null) {
			mListener = listener;
		}
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		mListener.onDataStart();
	}

	@Override
	protected T doInBackground(P... params) {
		try {
			return (T) mListener.doInWorkerThread(mDataType,params);
		} catch (Exception e) {
			e.printStackTrace();
			ex = e;
			return null;
		}
	}
	
	@Override
	protected void onProgressUpdate(S... values) {
		super.onProgressUpdate(values);
		
	}

	@Override
	protected void onPostExecute(T result) {
		super.onPostExecute(result);
		if (ex != null) {
			mListener.onDataFail(ex);
		} else {
			mListener.onDataGet(result);
		}
		mListener.onDataFinish();
	}

	@Override
	protected void onCancelled() {
		super.onCancelled();
		mListener.onDataFinish();
	}

	/**
	 * 
	 * @Description:异步数据回调接口类
	 * <p>创建日期:2013-9-3 </p>
	 * @version V1.0  
	 * @author LZP
	 * @see
	 */
	public interface OnLoadListener<P, S, T> {

		/**
		 * 
		 * @Description:异步数据加载开始时回调
		 * <p>创建人:LZP ,  2013-9-3  下午9:42:58</p>
		 * <p>修改人:LZP ,  2013-9-3  下午9:42:58</p>
		 *
		 * 
		 */
		void onDataStart();

		/**
		 * 
		 * @Description:异步数据请求回调,运行子线程中
		 * <p>创建人:LZP ,  2013-9-3  下午9:43:21</p>
		 * <p>修改人:LZP ,  2013-9-3  下午9:43:21</p>
		 *
		 * @param dataType
		 * @return
		 * @throws Exception
		 * 
		 */
		T doInWorkerThread(int dataType,P... params) throws Exception;
		
		/**
		 * 
		 * @Description:异步数据进行的进度回调,用来显示进度条或更新UI等
		 * <p>创建人:LZP ,  2013-9-3  下午9:43:21</p>
		 * <p>修改人:LZP ,  2013-9-3  下午9:43:21</p>
		 *
		 * @param values
		 * @return
		 * @throws Exception
		 * 
		 */
		void onDataProgress(S... values);

		/**
		 * 
		 * @Description:异步数据返回时回调
		 * <p>创建人:LZP ,  2013-9-3  下午9:43:59</p>
		 * <p>修改人:LZP ,  2013-9-3  下午9:43:59</p>
		 *
		 * @param result
		 * void
		 */
		void onDataGet(T result);

		/**
		 * 
		 * @Description:异步数据请求失败时回调
		 * <p>创建人:LZP ,  2013-9-3  下午9:44:21</p>
		 * <p>修改人:LZP ,  2013-9-3  下午9:44:21</p>
		 *
		 * @param e
		 * void
		 */
		void onDataFail(Exception e);

		/**
		 * 
		 * @Description:异步数据结束时回调
		 * <p>创建人:LZP ,  2013-9-3  下午9:44:43</p>
		 * <p>修改人:LZP ,  2013-9-3  下午9:44:43</p>
		 *
		 * void
		 */
		void onDataFinish();

	}

}


MainActivity类

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import com.common.asynctask.AsyncLoader;
import com.common.asynctask.AsyncLoader.OnLoadListener;

import android.R.integer;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity implements OnClickListener,OnLoadListener<Void, Integer, Bitmap>{

	private Button mButton;
	private ImageView mImageView;
	private AsyncLoader<Void, Integer, Bitmap> mLoader;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_layout);
		
		initView();
		
	}
	private void initView() {
		mButton = (Button) findViewById(R.id.button);
		mImageView = (ImageView) findViewById(R.id.iv);
		mButton.setOnClickListener(this);
	}
	/**
	 * 执行异步任务
	 * @param dataType 用来区分不同异步任务
	 */
	private void loadData(int dataType) {
		mLoader = new AsyncLoader<Void, Integer, Bitmap>(dataType);
		mLoader.setOnLoadListener(this);
		mLoader.execute();
	}
	//-----------------------------华丽的分割线---------------------------------------
	@Override
	public void onDataStart() {
		Log.i("mainactivity", "开始异步任务");
	}

	@Override
	public Bitmap doInWorkerThread(int dataType, Void... params)
			throws Exception {
		
		return returnBitMap("http://c.hiphotos.baidu.com/image/pic/item/6c224f4a20a446234b87678d9a22720e0df3d794.jpg");
	}
	//调用publishProgress()方法,才会执行此方法
	@Override
	public void onDataProgress(Integer... values) {
		Log.i("mainactivity", ""+values);
	}

	@Override
	public void onDataGet(Bitmap result) {
		Log.i("mainactivity", "获得异步任务结果");
		mImageView.setImageBitmap(result);
	}

	@Override
	public void onDataFail(Exception e) {
		Log.i("mainactivity", "异步任务失败");
	}

	@Override
	public void onDataFinish() {
		Log.i("mainactivity", "结束异步任务");
	}
	//-----------------------------华丽的分割线---------------------------------------
	@Override
	public void onClick(View v) {
		loadData(1);
	}
	/**
	 * 网络下载图片的方法
	 * @param url 图片地址
	 * @return
	 */
	private Bitmap returnBitMap(String url) {
		URL imUrl = null;
		Bitmap bitmap = null;
		try {
			imUrl = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			HttpURLConnection conn = (HttpURLConnection) imUrl.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();
			bitmap = BitmapFactory.decodeStream(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bitmap;
	}

}

虽然没简化多少,不过方法很清晰。大家有啥好的建议随时更新哈。

转载请注明出处。

源码传送门

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值