android异步操作

ctrip_xzh 2014-01-08

为了使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方法中传入的接口的参数也对应使用了泛型。至此,一个典型的异步调用的案例如下:

  1. this.doAsync(new Callable<String>() {  
  2.             // 希望异步加载的数据  
  3.             public String call() throws Exception {  
  4.                 String resu = NetworkTool.httpGetURL(  
  5.                              "http://www.baidu.com""GBK");  
  6.                 return resu;  
  7.             }  
  8.         }, new Callback<String>() {  
  9.             // 当加载完成后回调,在UI线程中的操作  
  10.             public void onCallback(final String resu) {  
  11.                 if (null != resu) {  
  12.                     tv_text1.setText(getRT().text1 + resu);  
  13.                 } else {  
  14.                     Tools.ShowNetErr(HomeActivity.this);  
  15.                 }  
  16.             }  
  17.         });  

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

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

附源码:

  1. public class ActivityUtils {  
  2.     public static <T> void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable<T> pCallable, final Callback<T> pCallback) {  
  3.         ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, nullfalse);  
  4.     }  
  5.     public static <T> void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable<T> pCallable, final Callback<T> pCallback) {  
  6.         ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, nullfalse);  
  7.     }  
  8.     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) {  
  9.         ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, pCancelable);  
  10.     }  
  11.     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) {  
  12.         ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, pCancelable);  
  13.     }  
  14.     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) {  
  15.         ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback, false);  
  16.     }  
  17.     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) {  
  18.         ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, pExceptionCallback, false);  
  19.     }  
  20.     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) {  
  21.         ActivityUtils.doAsync(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID), pCallable, pCallback, pExceptionCallback, pCancelable);  
  22.     }  
  23.     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) {  
  24.         new AsyncTask<Void, Void, T>() {  
  25.             private ProgressDialog mPD;  
  26.             private Exception mException = null;  
  27.             @Override  
  28.             public void onPreExecute() {  
  29.                 this.mPD = ProgressDialog.show(pContext, pTitle, pMessage, true, pCancelable);  
  30.                 if(pCancelable) {  
  31.                     this.mPD.setOnCancelListener(new OnCancelListener() {  
  32.                         @Override  
  33.                         public void onCancel(final DialogInterface pDialogInterface) {  
  34.                             pExceptionCallback.onCallback(new CancelledException());  
  35.                             pDialogInterface.dismiss();  
  36.                         }  
  37.                     });  
  38.                 }  
  39.                 super.onPreExecute();  
  40.             }  
  41.             @Override  
  42.             public T doInBackground(final Void... params) {  
  43.                 try {  
  44.                     return pCallable.call();  
  45.                 } catch (final Exception e) {  
  46.                     this.mException = e;  
  47.                 }  
  48.                 return null;  
  49.             }  
  50.             @Override  
  51.             public void onPostExecute(final T result) {  
  52.                 try {  
  53.                     this.mPD.dismiss();  
  54.                 } catch (final Exception e) {  
  55.                     Log.e("Error", e.toString());  
  56.                 }  
  57.                 if(this.isCancelled()) {  
  58.                     this.mException = new CancelledException();  
  59.                 }  
  60.                 if(this.mException == null) {  
  61.                     pCallback.onCallback(result);  
  62.                 } else {  
  63.                     if(pExceptionCallback == null) {  
  64.                         if (this.mException != null)  
  65.                             Log.e("Error"this.mException.toString());  
  66.                     } else {  
  67.                         pExceptionCallback.onCallback(this.mException);  
  68.                     }  
  69.                 }  
  70.                 super.onPostExecute(result);  
  71.             }  
  72.         }.execute((Void[]) null);  
  73.     }  
  74.     public static <T> void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback) {  
  75.         ActivityUtils.doProgressAsync(pContext, pTitleResID, pCallable, pCallback, null);  
  76.     }  
  77.     public static <T> void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {  
  78.         new AsyncTask<Void, Integer, T>() {  
  79.             private ProgressDialog mPD;  
  80.             private Exception mException = null;  
  81.             @Override  
  82.             public void onPreExecute() {  
  83.                 this.mPD = new ProgressDialog(pContext);  
  84.                 this.mPD.setTitle(pTitleResID);  
  85.                 this.mPD.setIcon(android.R.drawable.ic_menu_save);  
  86.                 this.mPD.setIndeterminate(false);  
  87.                 this.mPD.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  88.                 this.mPD.show();  
  89.                 super.onPreExecute();  
  90.             }  
  91.             @Override  
  92.             public T doInBackground(final Void... params) {  
  93.                 try {  
  94.                     return pCallable.call(new IProgressListener() {  
  95.                         @Override  
  96.                         public void onProgressChanged(final int pProgress) {  
  97.                             onProgressUpdate(pProgress);  
  98.                         }  
  99.                     });  
  100.                 } catch (final Exception e) {  
  101.                     this.mException = e;  
  102.                 }  
  103.                 return null;  
  104.             }  
  105.             @Override  
  106.             public void onProgressUpdate(final Integer... values) {  
  107.                 this.mPD.setProgress(values[0]);  
  108.             }  
  109.             @Override  
  110.             public void onPostExecute(final T result) {  
  111.                 try {  
  112.                     this.mPD.dismiss();  
  113.                 } catch (final Exception e) {  
  114.                     Log.e("Error", e.getLocalizedMessage());  
  115.                     /* Nothing. */  
  116.                 }  
  117.                 if(this.isCancelled()) {  
  118.                     this.mException = new CancelledException();  
  119.                 }  
  120.                 if(this.mException == null) {  
  121.                     pCallback.onCallback(result);  
  122.                 } else {  
  123.                     if(pExceptionCallback == null) {  
  124.                         Log.e("Error"this.mException.getLocalizedMessage());  
  125.                     } else {  
  126.                         pExceptionCallback.onCallback(this.mException);  
  127.                     }  
  128.                 }  
  129.                 super.onPostExecute(result);  
  130.             }  
  131.         }.execute((Void[]) null);  
  132.     }  
  133.     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) {  
  134.         final ProgressDialog pd = ProgressDialog.show(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID));  
  135.         pAsyncCallable.call(new Callback<T>() {  
  136.             @Override  
  137.             public void onCallback(final T result) {  
  138.                 try {  
  139.                     pd.dismiss();  
  140.                 } catch (final Exception e) {  
  141.                     Log.e("Error", e.getLocalizedMessage());  
  142.                     /* Nothing. */  
  143.                 }  
  144.                 pCallback.onCallback(result);  
  145.             }  
  146.         }, pExceptionCallback);  
  147.     }  
  148.       
  149.     public static class CancelledException extends Exception {  
  150.         private static final long serialVersionUID = -78123211381435595L;  
  151.     }  
  152. }  

 

  1. public interface AsyncCallable<T> {  
  2.     // ===========================================================  
  3.     // Final Fields  
  4.     // ===========================================================  
  5.     // ===========================================================  
  6.     // Methods  
  7.     // ===========================================================  
  8.     /** 
  9.      * Computes a result asynchronously, return values and exceptions are to be handled through the callbacks. 
  10.      * This method is expected to return almost immediately, after starting a {@link Thread} or similar. 
  11.      * 
  12.      * @return computed result 
  13.      * @throws Exception if unable to compute a result 
  14.      */  
  15.     public void call(final Callback<T> pCallback, final Callback<Exception> pExceptionCallback);  
  16. }  

 

  1. public interface Callback<T> {  
  2.     // ===========================================================  
  3.     // Final Fields  
  4.     // ===========================================================  
  5.     // ===========================================================  
  6.     // Methods  
  7.     // ===========================================================  
  8.     /** 
  9.      * 当加载完成后回调,加载完毕的事后处理   
  10.      */  
  11.     public void onCallback(final T pCallbackValue);  
  12. }  

 

  1. public interface IProgressListener {  
  2.     // ===========================================================  
  3.     // Constants  
  4.     // ===========================================================  
  5.     // ===========================================================  
  6.     // Methods  
  7.     // ===========================================================  
  8.     /** 
  9.      * @param pProgress between 0 and 100. 
  10.      */  
  11.     public void onProgressChanged(final int pProgress);  
  12. }  

 

  1. public interface IProgressListener {  
  2.     // ===========================================================  
  3.     // Constants  
  4.     // ===========================================================  
  5.     // ===========================================================  
  6.     // Methods  
  7.     // ===========================================================  
  8.     /** 
  9.      * @param pProgress between 0 and 100. 
  10.      */  
  11.     public void onProgressChanged(final int pProgress);  
  12. }  

 

  1. public class BaseActivity extends Activity {  
  2.       
  3.     /** 
  4.      *  
  5.      * @param <T> 模板参数,操作时要返回的内容 
  6.      * @param pCallable 需要异步调用的操作 
  7.      * @param pCallback 回调 
  8.      */  
  9.     protected <T> void doAsync(final Callable<T> pCallable, final Callback<T> pCallback) {  
  10.         ActivityUtils.doAsync(thisnull"内容读取中,请稍等...", pCallable, pCallback, nullfalse);  
  11.     }  
  12.       
  13.     protected <T> void doAsync(final CharSequence pTitle, final CharSequence pMessage, final Callable<T> pCallable, final Callback<T> pCallback) {  
  14.         ActivityUtils.doAsync(this, pTitle, pMessage, pCallable, pCallback, nullfalse);  
  15.     }  
  16.       
  17.     /** 
  18.      * Performs a task in the background, showing a {@link ProgressDialog}, 
  19.      * while the {@link Callable} is being processed. 
  20.      *  
  21.      * @param <T> 
  22.      * @param pTitleResID 
  23.      * @param pMessageResID 
  24.      * @param pErrorMessageResID 
  25.      * @param pCallable 
  26.      * @param pCallback 
  27.      */  
  28.     protected <T> void doAsync(final int pTitleResID, final int pMessageResID, final Callable<T> pCallable, final Callback<T> pCallback) {  
  29.         this.doAsync(pTitleResID, pMessageResID, pCallable, pCallback, null);  
  30.     }  
  31.     /** 
  32.      * Performs a task in the background, showing a indeterminate {@link ProgressDialog}, 
  33.      * while the {@link Callable} is being processed. 
  34.      *  
  35.      * @param <T> 
  36.      * @param pTitleResID 
  37.      * @param pMessageResID 
  38.      * @param pErrorMessageResID 
  39.      * @param pCallable 
  40.      * @param pCallback 
  41.      * @param pExceptionCallback 
  42.      */  
  43.     protected <T> void doAsync(final int pTitleResID, final int pMessageResID, final Callable<T> pCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {  
  44.         ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback);  
  45.     }  
  46.     /** 
  47.      * Performs a task in the background, showing a {@link ProgressDialog} with an ProgressBar, 
  48.      * while the {@link AsyncCallable} is being processed. 
  49.      *  
  50.      * @param <T> 
  51.      * @param pTitleResID 
  52.      * @param pMessageResID 
  53.      * @param pErrorMessageResID 
  54.      * @param pAsyncCallable 
  55.      * @param pCallback 
  56.      */  
  57.     protected <T> void doProgressAsync(final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback) {  
  58.         this.doProgressAsync(pTitleResID, pCallable, pCallback, null);  
  59.     }  
  60.     /** 
  61.      * Performs a task in the background, showing a {@link ProgressDialog} with a ProgressBar, 
  62.      * while the {@link AsyncCallable} is being processed. 
  63.      *  
  64.      * @param <T> 
  65.      * @param pTitleResID 
  66.      * @param pMessageResID 
  67.      * @param pErrorMessageResID 
  68.      * @param pAsyncCallable 
  69.      * @param pCallback 
  70.      * @param pExceptionCallback 
  71.      */  
  72.     protected <T> void doProgressAsync(final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {  
  73.         ActivityUtils.doProgressAsync(this, pTitleResID, pCallable, pCallback, pExceptionCallback);  
  74.     }  
  75.     /** 
  76.      * Performs a task in the background, showing an indeterminate {@link ProgressDialog}, 
  77.      * while the {@link AsyncCallable} is being processed. 
  78.      *  
  79.      * @param <T> 
  80.      * @param pTitleResID 
  81.      * @param pMessageResID 
  82.      * @param pErrorMessageResID 
  83.      * @param pAsyncCallable 
  84.      * @param pCallback 
  85.      * @param pExceptionCallback 
  86.      */  
  87.     protected <T> void doAsync(final int pTitleResID, final int pMessageResID, final AsyncCallable<T> pAsyncCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {  
  88.         ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pAsyncCallable, pCallback, pExceptionCallback);  
  89.     }  

登录 后评论
下一篇
云栖号资讯小编
777人浏览
2020-05-25
相关推荐
android AsyncTask介绍
990人浏览
2014-12-01 23:33:00
Android集成测试
1966人浏览
2017-07-10 13:41:00
Android AsyncTask异步线程
731人浏览
2013-06-14 11:00:00
AsyncTask和Handler对比(转)
529人浏览
2014-04-04 18:10:00
Android -- AsyncTask
553人浏览
2017-08-27 22:31:00
android AsyncTask介绍
569人浏览
2014-12-16 14:56:20
Android应用开发—AsyncTask
685人浏览
2018-01-27 15:28:44
0
0
0
772