对于android的异步操作,往往有二种方法给予我们选择。
一:Thread+Handler
二: AsyncTask
对于二者的相同与异同点,这里并不去进行比较。这里提供一种简化异步操作的方法,供大家参考学习。
代码参考自AndEngine,不过我对它做了一定的修改,让它更适合自己目前项目的开发,感谢open source 能够让我们去学习和阅读那么多优秀的代码。
废话不多说,代码如下:
CallEarliest<T>:
/** * * 回调接口,回调方法运行于主线程 * @ClassName: CallEarliest * @author 姜涛 * @version 1.0 2012-1-16 下午11:23:41 * @param <T> */ public interface CallEarliest<T> { public void onCallEarliest() throws Exception; }
Callable<T>:
/**
* 回调接口,回调方法运行于异步线程 * @ClassName: Callable * @author 姜涛 * @version 1.0 2012-1-16 下午5:56:42 * @param <T> */ public interface Callable<T> { public T call() throws Exception; }
Callback<T>:
/**
* 回调接口,回调方法运行于主线程 * @ClassName: Callback * @author 姜涛 * @version 1.0 2012-1-16 下午5:58:16 * @param <T> */ public interface Callback<T> { public void onCallback(final T pCallbackValue); }
IProgressListener:
/**
* 观察者 * @ClassName: IProgressListener * @author 姜涛 * @version 1.0 2012-1-16 下午11:08:40 */ public interface IProgressListener { /** * 进度发生改变的时候调用 * @param pProgress */ public void onProgressChanged(final int pProgress); }
ProgressCallable<T>:
/** * 被观察者 * @ClassName: ProgressCallable * @author 姜涛 * @version 1.0 2012-1-16 下午11:08:52 * @param <T> */ public interface ProgressCallable<T> { /** * 注册观察者对象 * @param pProgressListener * @return * @throws Exception */ public T call(final IProgressListener pProgressListener) throws Exception; }
AsyncTaskUtils:
/** * 异步操作工具类 * @ClassName: ActivityUtils * @author 姜涛 * @version 1.0 2012-1-16 下午11:02:26 */ public class AsyncTaskUtils { /** * 封装的asynctask方法,此方法没有进度框. * * @param pCallEarliest * 运行于主线程,最先执行此方法. * @param mCallable * 运行于异步线程,第二执行此方法. * @param mCallback * 运行于主线程,最后执行此方法. */ public static <T> void doAsync(final CallEarliest<T> pCallEarliest, final Callable<T> pCallable, final Callback<T> pCallback) { new AsyncTask<Void, Void, T>() { /** * 首先运行此方法,运行于主线程 */ @Override protected void onPreExecute() { super.onPreExecute(); try { pCallEarliest.onCallEarliest(); } catch (Exception e) { Log.e("error", e.toString()); } } /** * 第二步执行这个方法,这个方法运行在异步线程中 */ @Override protected T doInBackground(Void... params) { try { return pCallable.call(); } catch (Exception e) { Log.e("error", e.toString()); } return null; } /** * 第三步执行这个方法,运行于主线程 */ protected void onPostExecute(T result) { pCallback.onCallback(result); } }.execute((Void[]) null); } /** * 封装的asynctask方法,此方法拥有进度对话框,并支持定义样式. * * @param pContext * 上下文 * @param styleID * 对话框样式 * ProgressDialog.STYLE_HORIZONTAL|ProgressDialog.STYLE_SPINNER * @param pTitle * 标题 * @param pMessage * 内容 * @param pCallEarliest * 运行于主线程,最先执行此方法. * @param progressCallable * 运行于异步线程,用于传递对话框进度. * @param pCallback * 运行于主线程,最后执行此方法. */ public static <T> void doProgressAsync(final Context pContext, final int styleID, final String pTitle, final String pMessage, final CallEarliest<T> pCallEarliest, final ProgressCallable<T> progressCallable, final Callback<T> pCallback) { new AsyncTask<Void, Void, T>() { private ProgressDialog mProgressDialog; /** * 首先运行此方法,运行于主线程 */ @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog = new ProgressDialog(pContext); mProgressDialog.setProgressStyle(styleID); mProgressDialog.setTitle(pTitle); mProgressDialog.setMessage(pMessage); mProgressDialog.setIndeterminate(false); mProgressDialog.show(); try { pCallEarliest.onCallEarliest(); } catch (Exception e) { Log.e("error", e.toString()); } } /** * 第二步执行这个方法,这个方法运行在异步线程中 */ @Override protected T doInBackground(Void... params) { try { return progressCallable.call(new IProgressListener() { @Override public void onProgressChanged(int pProgress) { // TODO Auto-generated method stub onProgressUpdate(pProgress); } }); } catch (Exception e) { Log.e("error", e.toString()); } return null; } /** * 更新进度框 */ protected void onProgressUpdate(final Integer... values) { mProgressDialog.setProgress(values[0]); }; /** * 第三步执行这个方法,运行于主线程 */ protected void onPostExecute(T result) { if (mProgressDialog != null) mProgressDialog.dismiss(); pCallback.onCallback(result); } }.execute((Void[]) null); } /** * 封装的asynctask方法,此方法拥有进度对话框,并支持定义样式. * * @param pContext * 上下文 * @param styleID * 对话框样式 * ProgressDialog.STYLE_HORIZONTAL|ProgressDialog.STYLE_SPINNER * @param pTitle * 标题,资源id * @param pMessage * 内容,资源id * @param pCallEarliest * 运行于主线程,最先执行此方法. * @param progressCallable * 运行于异步线程,用于传递对话框进度. * @param pCallback * 运行于主线程,最后执行此方法. */ public static <T> void doProgressAsync(final Context pContext, final int styleID, final int pTitleResId, final int pMessageResId, final CallEarliest<T> pCallEarliest, final ProgressCallable<T> progressCallable, final Callback<T> pCallback) { AsyncTaskUtils.doProgressAsync(pContext, styleID, pContext.getString(pTitleResId), pContext.getString(pMessageResId), pCallEarliest, progressCallable, pCallback); } }
BaseActivity:
/** * 公用Activity,用于存放与业务无关的公用方法 * * @ClassName: BaseActivity * @author 姜涛 * @version 1.0 2011-12-11 下午7:03:18 */ public abstract class BaseActivity extends Activity { /** * 封装的asynctask方法,此方法没有进度框. * * @param pCallEarliest 运行于主线程,最先执行此方法. * @param mCallable 运行于异步线程,第二执行此方法. * @param mCallback 运行于主线程,最后执行此方法. */ public <T> void doAsync(final CallEarliest<T> pCallEarliest, final Callable<T> mCallable, final Callback<T> mCallback) { AsyncTaskUtils.doAsync(pCallEarliest, mCallable, mCallback); } /** * 封装的asynctask方法,此方法拥有进度对话框,并支持定义样式. * @param pContext 上下文 * @param styleID 对话框样式 ProgressDialog.STYLE_HORIZONTAL|ProgressDialog.STYLE_SPINNER * @param pTitle 标题 * @param pMessage 内容 * @param pCallEarliest 运行于主线程,最先执行此方法. * @param progressCallable 运行于异步线程,用于传递对话框进度. * @param pCallback 运行于主线程,最后执行此方法. */ public <T> void doProgressAsync(final Context pContext, final int styleID, final String pTitleResID, final String pMessageResID, final CallEarliest<T> pCallEarliest, final ProgressCallable<T> pCallable, final Callback<T> pCallback) { AsyncTaskUtils.doProgressAsync(pContext, styleID, pTitleResID, pMessageResID, pCallEarliest, pCallable, pCallback); } /** * 封装的asynctask方法,此方法拥有进度对话框,并支持定义样式. * @param pContext 上下文 * @param styleID 对话框样式 ProgressDialog.STYLE_HORIZONTAL|ProgressDialog.STYLE_SPINNER * @param pTitle 标题,资源id * @param pMessage 内容,资源id * @param pCallEarliest 运行于主线程,最先执行此方法. * @param progressCallable 运行于异步线程,用于传递对话框进度. * @param pCallback 运行于主线程,最后执行此方法. */ public <T> void doProgressAsync(final Context pContext, final int styleID, final int pTitleResID, final int pMessageResID, final CallEarliest<T> pCallEarliest, final ProgressCallable<T> pCallable, final Callback<T> pCallback) { AsyncTaskUtils.doProgressAsync(pContext, styleID, pTitleResID, pMessageResID, pCallEarliest, pCallable, pCallback); } }
SimpleAsyncTaskActivity:
public class SimpleAsyncTaskActivity extends BaseActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.doProgressAsync(this, ProgressDialog.STYLE_HORIZONTAL, R.string.app_name, R.string.app_name, new CallEarliest<Void>() { @Override public void onCallEarliest() throws Exception { // TODO Auto-generated method stub } }, new ProgressCallable<Void>() { @Override public Void call(IProgressListener pProgressListener) throws Exception { // TODO Auto-generated method stub for (int i = 0; i < 100; i++) { Thread.sleep(200); pProgressListener.onProgressChanged(i); } return null; } }, new Callback<Void>() { @Override public void onCallback(Void pCallbackValue) { // TODO Auto-generated method stub } }); } }
效果图:
示例可参见附件.