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

来源:互联网 发布:r.java是什么文件 编辑:程序博客网 时间:2024/05/16 07:10

之前封装过很多工具类,一直没有整理,结果回过头要用的时候往往找起来很麻烦。一直想整理一下,结果不是没时间就是懒,不是懒就是没时间。今天群里有人问到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>() {@Overridepublic void onDataStart() {}@Overridepublic T doInWorkerThread(int dataType, P... params)throws Exception {return null;}@Overridepublic void onDataGet(T result) {}@Overridepublic void onDataFail(Exception e) {}@Overridepublic void onDataFinish() {}@Overridepublic void onDataProgress(S... values) {}};}public void setOnLoadListener(OnLoadListener<P, S, T> listener) {if (listener != null) {mListener = listener;}}@Overrideprotected void onPreExecute() {super.onPreExecute();mListener.onDataStart();}@Overrideprotected T doInBackground(P... params) {try {return (T) mListener.doInWorkerThread(mDataType,params);} catch (Exception e) {e.printStackTrace();ex = e;return null;}}@Overrideprotected void onProgressUpdate(S... values) {super.onProgressUpdate(values);}@Overrideprotected void onPostExecute(T result) {super.onPostExecute(result);if (ex != null) {mListener.onDataFail(ex);} else {mListener.onDataGet(result);}mListener.onDataFinish();}@Overrideprotected 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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();}//-----------------------------华丽的分割线---------------------------------------@Overridepublic void onDataStart() {Log.i("mainactivity", "开始异步任务");}@Overridepublic Bitmap doInWorkerThread(int dataType, Void... params)throws Exception {return returnBitMap("http://c.hiphotos.baidu.com/image/pic/item/6c224f4a20a446234b87678d9a22720e0df3d794.jpg");}//调用publishProgress()方法,才会执行此方法@Overridepublic void onDataProgress(Integer... values) {Log.i("mainactivity", ""+values);}@Overridepublic void onDataGet(Bitmap result) {Log.i("mainactivity", "获得异步任务结果");mImageView.setImageBitmap(result);}@Overridepublic void onDataFail(Exception e) {Log.i("mainactivity", "异步任务失败");}@Overridepublic void onDataFinish() {Log.i("mainactivity", "结束异步任务");}//-----------------------------华丽的分割线---------------------------------------@Overridepublic 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 0
原创粉丝点击