zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

android异步操作详解手机开发

2023-06-13 09:20:14 时间

为了使UI在数据获取时不僵死,数据获取需要在新开Worker线程中进行,然后将返回结果在UI线程中进行读取并渲染页面。面对这种异步处理,到底如何写才简洁,先后面临过三种实现方式。

首先是最原始的Java方式,new 一个Thread出来,将处理Runnable进去执行,执行完之后通过handler post到ui线程去更新界面。然后发现1.5后有了AsyncTask,非常好用,以后的项目中全部改成衍生出一个AsyncTask的子类,类中自然定义了运行前方法、运行中方法和运行后在ui中运行的方法。目前我做的项目中对AsyncTask做了封装,把它从原本的子类编写的过程,改成了函数调用方式,这就是目前正使用的第三种方法。

clip_image001

一个Android应用中,Activity通常可以建立以上层次关系。然后,在BaseActivity中对AsyncTask进行了封装,形成doAsync方法。方法体内创建一个新的AsyncTask并执行,由于AsyncTask是泛型参数,doAsync方法中传入的接口的参数也对应使用了泛型。至此,一个典型的异步调用的案例如下:


[java]
view plain
copy this.doAsync(new Callable String () {   // 希望异步加载的数据   public String call() throws Exception {   String resu = NetworkTool.httpGetURL(    http://www.baidu.com ,  GBK );   return resu;   }   }, new Callback String () {   // 当加载完成后回调,在UI线程中的操作   public void onCallback(final String resu) {   if (null != resu) {   tv_text1.setText(getRT().text1 + resu);   } else {   Tools.ShowNetErr(HomeActivity.this);   }   }   }); 

这样,就从本来继承AsyncTask创建一个子类,然后初始化,然后运行的开发过程转变为了函数调用的过程。可以看到,调用可是简洁了很多!

为了实现它,我们附上BaseActivity中如下封装代码,需要说明的是这不是我的原创,我借鉴于Andengine引擎的实现代码进行的修改。

附源码:


[java]
view plain
copy public class ActivityUtils {   public static  T  void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable T  pCallable, final Callback T  pCallback) {   ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, false);   }   public static  T  void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable T  pCallable, final Callback T  pCallback) {   ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, false);   }   public static  T  void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable T  pCallable, final Callback T  pCallback, final boolean pCancelable) {   ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, pCancelable);   }   public static  T  void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable T  pCallable, final Callback T  pCallback, final boolean pCancelable) {   ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, pCancelable);   }   public static  T  void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback, false);   }   public static  T  void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, pExceptionCallback, false);   }   public static  T  void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback, final boolean pCancelable) {   ActivityUtils.doAsync(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID), pCallable, pCallback, pExceptionCallback, pCancelable);   }   public static  T  void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback, final boolean pCancelable) {   new AsyncTask Void, Void, T () {   private ProgressDialog mPD;   private Exception mException = null;   @Override   public void onPreExecute() {   this.mPD = ProgressDialog.show(pContext, pTitle, pMessage, true, pCancelable);   if(pCancelable) {   this.mPD.setOnCancelListener(new OnCancelListener() {   @Override   public void onCancel(final DialogInterface pDialogInterface) {   pExceptionCallback.onCallback(new CancelledException());   pDialogInterface.dismiss();   }   });   }   super.onPreExecute();   }   @Override   public T doInBackground(final Void  params) {   try {   return pCallable.call();   } catch (final Exception e) {   this.mException = e;   }   return null;   }   @Override   public void onPostExecute(final T result) {   try {   this.mPD.dismiss();   } catch (final Exception e) {   Log.e( Error , e.toString());   }   if(this.isCancelled()) {   this.mException = new CancelledException();   }   if(this.mException == null) {   pCallback.onCallback(result);   } else {   if(pExceptionCallback == null) {   if (this.mException != null)   Log.e( Error , this.mException.toString());   } else {   pExceptionCallback.onCallback(this.mException);   }   }   super.onPostExecute(result);   }   }.execute((Void[]) null);   }   public static  T  void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable T  pCallable, final Callback T  pCallback) {   ActivityUtils.doProgressAsync(pContext, pTitleResID, pCallable, pCallback, null);   }   public static  T  void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   new AsyncTask Void, Integer, T () {   private ProgressDialog mPD;   private Exception mException = null;   @Override   public void onPreExecute() {   this.mPD = new ProgressDialog(pContext);   this.mPD.setTitle(pTitleResID);   this.mPD.setIcon(android.R.drawable.ic_menu_save);   this.mPD.setIndeterminate(false);   this.mPD.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);   this.mPD.show();   super.onPreExecute();   }   @Override   public T doInBackground(final Void  params) {   try {   return pCallable.call(new IProgressListener() {   @Override   public void onProgressChanged(final int pProgress) {   onProgressUpdate(pProgress);   }   });   } catch (final Exception e) {   this.mException = e;   }   return null;   }   @Override   public void onProgressUpdate(final Integer  values) {   this.mPD.setProgress(values[0]);   }   @Override   public void onPostExecute(final T result) {   try {   this.mPD.dismiss();   } catch (final Exception e) {   Log.e( Error , e.getLocalizedMessage());   /* Nothing. */   }   if(this.isCancelled()) {   this.mException = new CancelledException();   }   if(this.mException == null) {   pCallback.onCallback(result);   } else {   if(pExceptionCallback == null) {   Log.e( Error , this.mException.getLocalizedMessage());   } else {   pExceptionCallback.onCallback(this.mException);   }   }   super.onPostExecute(result);   }   }.execute((Void[]) null);   }   public static  T  void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final AsyncCallable T  pAsyncCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   final ProgressDialog pd = ProgressDialog.show(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID));   pAsyncCallable.call(new Callback T () {   @Override   public void onCallback(final T result) {   try {   pd.dismiss();   } catch (final Exception e) {   Log.e( Error , e.getLocalizedMessage());   /* Nothing. */   }   pCallback.onCallback(result);   }   }, pExceptionCallback);   }     public static class CancelledException extends Exception {   private static final long serialVersionUID = -78123211381435595L;   }  } 
[java]
view plain
copy public interface AsyncCallable T  {   // ===========================================================   // Final Fields   // ===========================================================   // ===========================================================   // Methods   // ===========================================================   /**   * Computes a result asynchronously, return values and exceptions are to be handled through the callbacks.   * This method is expected to return almost immediately, after starting a [email protected] Thread} or similar.   *   * @return computed result   * @throws Exception if unable to compute a result   */   public void call(final Callback T  pCallback, final Callback Exception  pExceptionCallback);  } 
[java]
view plain
copy public interface Callback T  {   // ===========================================================   // Final Fields   // ===========================================================   // ===========================================================   // Methods   // ===========================================================   /**   * 当加载完成后回调,加载完毕的事后处理   */   public void onCallback(final T pCallbackValue);  } 
[java]
view plain
copy public interface IProgressListener {   // ===========================================================   // Constants   // ===========================================================   // ===========================================================   // Methods   // ===========================================================   /**   * @param pProgress between 0 and 100.   */   public void onProgressChanged(final int pProgress);  } 
[java]
view plain
copy public interface IProgressListener {   // ===========================================================   // Constants   // ===========================================================   // ===========================================================   // Methods   // ===========================================================   /**   * @param pProgress between 0 and 100.   */   public void onProgressChanged(final int pProgress);  } 
[java]
view plain
copy public class BaseActivity extends Activity {     /**   *   * @param  T  模板参数,操作时要返回的内容   * @param pCallable 需要异步调用的操作   * @param pCallback 回调   */   protected  T  void doAsync(final Callable T  pCallable, final Callback T  pCallback) {   ActivityUtils.doAsync(this, null,  内容读取中,请稍等 , pCallable, pCallback, null, false);   }     protected  T  void doAsync(final CharSequence pTitle, final CharSequence pMessage, final Callable T  pCallable, final Callback T  pCallback) {   ActivityUtils.doAsync(this, pTitle, pMessage, pCallable, pCallback, null, false);   }     /**   * Performs a task in the background, showing a [email protected] ProgressDialog},   * while the [email protected] Callable} is being processed.   *   * @param  T    * @param pTitleResID   * @param pMessageResID   * @param pErrorMessageResID   * @param pCallable   * @param pCallback   */   protected  T  void doAsync(final int pTitleResID, final int pMessageResID, final Callable T  pCallable, final Callback T  pCallback) {   this.doAsync(pTitleResID, pMessageResID, pCallable, pCallback, null);   }   /**   * Performs a task in the background, showing a indeterminate [email protected] ProgressDialog},   * while the [email protected] Callable} is being processed.   *   * @param  T    * @param pTitleResID   * @param pMessageResID   * @param pErrorMessageResID   * @param pCallable   * @param pCallback   * @param pExceptionCallback   */   protected  T  void doAsync(final int pTitleResID, final int pMessageResID, final Callable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback);   }   /**   * Performs a task in the background, showing a [email protected] ProgressDialog} with an ProgressBar,   * while the [email protected] AsyncCallable} is being processed.   *   * @param  T    * @param pTitleResID   * @param pMessageResID   * @param pErrorMessageResID   * @param pAsyncCallable   * @param pCallback   */   protected  T  void doProgressAsync(final int pTitleResID, final ProgressCallable T  pCallable, final Callback T  pCallback) {   this.doProgressAsync(pTitleResID, pCallable, pCallback, null);   }   /**   * Performs a task in the background, showing a [email protected] ProgressDialog} with a ProgressBar,   * while the [email protected] AsyncCallable} is being processed.   *   * @param  T    * @param pTitleResID   * @param pMessageResID   * @param pErrorMessageResID   * @param pAsyncCallable   * @param pCallback   * @param pExceptionCallback   */   protected  T  void doProgressAsync(final int pTitleResID, final ProgressCallable T  pCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   ActivityUtils.doProgressAsync(this, pTitleResID, pCallable, pCallback, pExceptionCallback);   }   /**   * Performs a task in the background, showing an indeterminate [email protected] ProgressDialog},   * while the [email protected] AsyncCallable} is being processed.   *   * @param  T    * @param pTitleResID   * @param pMessageResID   * @param pErrorMessageResID   * @param pAsyncCallable   * @param pCallback   * @param pExceptionCallback   */   protected  T  void doAsync(final int pTitleResID, final int pMessageResID, final AsyncCallable T  pAsyncCallable, final Callback T  pCallback, final Callback Exception  pExceptionCallback) {   ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pAsyncCallable, pCallback, pExceptionCallback);   }  }