对于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
}
});
}
}
效果图:
示例可参见附件.