閱讀382 返回首頁    go 阿裏雲 go 技術社區[雲棲]


android異步操作

為了使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.                              "https://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.     }  

最後更新:2017-04-03 12:54:24

  上一篇:go sql server判斷某個表是否存在
  下一篇:go C#移位運算(左移和右移)