Android Trick 11: 對Android中的AsyncTask進行函數化的封裝,簡潔調用

來源:互聯網
上載者:User

為了使UI在資料擷取時不僵死,資料擷取需要在新開Worker線程中進行,然後將返回結果在UI線程中進行讀取並渲染頁面。面對這種非同步處理,到底如何寫才簡潔,先後面臨過三種實現方式。

首先是最原始的Java方式,new 一個Thread出來,將處理Runnable進去執行,執行完之後通過handler post到ui線程去更新介面。然後發現1.5後有了AsyncTask,非常好用,以後的項目中全部改成衍生出一個AsyncTask的子類,類中自然定義了運行前方法、運行中方法和運行後在ui中啟動並執行方法。目前我做的項目中對AsyncTask做了封裝,把它從原本的子類編寫的過程,改成了函數調用方式,這就是目前正使用的第三種方法。

一個Android應用中,Activity通常可以建立以上層次關係。然後,在BaseActivity中對AsyncTask進行了封裝,形成doAsync方法。方法體內建立一個新的AsyncTask並執行,由於AsyncTask是泛型參數,doAsync方法中傳入的介面的參數也對應使用了泛型。至此,一個典型的非同步呼叫的案例如下:

this.doAsync(new Callable<String>() {<br /> // 希望非同步載入的資料<br /> public String call() throws Exception {<br /> String resu = NetworkTool.httpGetURL(<br /> "http://www.baidu.com", "GBK");<br /> return resu;<br /> }<br /> }, new Callback<String>() {<br /> // 當載入完成後回調,在UI線程中的操作<br /> public void onCallback(final String resu) {<br /> if (null != resu) {<br /> tv_text1.setText(getRT().text1 + resu);<br /> } else {<br /> Tools.ShowNetErr(HomeActivity.this);<br /> }<br /> }<br /> });<br />

這樣,就從本來繼承AsyncTask建立一個子類,然後初始化,然後啟動並執行開發過程轉變為了函數調用的過程。可以看到,調用可是簡潔了很多!

為了實現它,我們附上BaseActivity中如下封裝代碼,需要說明的是這不是我的原創,我借鑒於Andengine引擎的實現代碼進行的修改。

附源碼:

public class ActivityUtils {<br />public static <T> void doAsync(final Context pContext, final int pTitleResID, final int pMessageResID, final Callable<T> pCallable, final Callback<T> pCallback) {<br />ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, false);<br />}<br />public static <T> void doAsync(final Context pContext, final CharSequence pTitle, final CharSequence pMessage, final Callable<T> pCallable, final Callback<T> pCallback) {<br />ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, false);<br />}<br />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) {<br />ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, null, pCancelable);<br />}<br />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) {<br />ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, null, pCancelable);<br />}<br />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) {<br />ActivityUtils.doAsync(pContext, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback, false);<br />}<br />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) {<br />ActivityUtils.doAsync(pContext, pTitle, pMessage, pCallable, pCallback, pExceptionCallback, false);<br />}<br />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) {<br />ActivityUtils.doAsync(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID), pCallable, pCallback, pExceptionCallback, pCancelable);<br />}<br />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) {<br />new AsyncTask<Void, Void, T>() {<br />private ProgressDialog mPD;<br />private Exception mException = null;<br />@Override<br />public void onPreExecute() {<br />this.mPD = ProgressDialog.show(pContext, pTitle, pMessage, true, pCancelable);<br />if(pCancelable) {<br />this.mPD.setOnCancelListener(new OnCancelListener() {<br />@Override<br />public void onCancel(final DialogInterface pDialogInterface) {<br />pExceptionCallback.onCallback(new CancelledException());<br />pDialogInterface.dismiss();<br />}<br />});<br />}<br />super.onPreExecute();<br />}<br />@Override<br />public T doInBackground(final Void... params) {<br />try {<br />return pCallable.call();<br />} catch (final Exception e) {<br />this.mException = e;<br />}<br />return null;<br />}<br />@Override<br />public void onPostExecute(final T result) {<br />try {<br />this.mPD.dismiss();<br />} catch (final Exception e) {<br />Log.e("Error", e.toString());<br />}<br />if(this.isCancelled()) {<br />this.mException = new CancelledException();<br />}<br />if(this.mException == null) {<br />pCallback.onCallback(result);<br />} else {<br />if(pExceptionCallback == null) {<br />if (this.mException != null)<br />Log.e("Error", this.mException.toString());<br />} else {<br />pExceptionCallback.onCallback(this.mException);<br />}<br />}<br />super.onPostExecute(result);<br />}<br />}.execute((Void[]) null);<br />}<br />public static <T> void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback) {<br />ActivityUtils.doProgressAsync(pContext, pTitleResID, pCallable, pCallback, null);<br />}<br />public static <T> void doProgressAsync(final Context pContext, final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {<br />new AsyncTask<Void, Integer, T>() {<br />private ProgressDialog mPD;<br />private Exception mException = null;<br />@Override<br />public void onPreExecute() {<br />this.mPD = new ProgressDialog(pContext);<br />this.mPD.setTitle(pTitleResID);<br />this.mPD.setIcon(android.R.drawable.ic_menu_save);<br />this.mPD.setIndeterminate(false);<br />this.mPD.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);<br />this.mPD.show();<br />super.onPreExecute();<br />}<br />@Override<br />public T doInBackground(final Void... params) {<br />try {<br />return pCallable.call(new IProgressListener() {<br />@Override<br />public void onProgressChanged(final int pProgress) {<br />onProgressUpdate(pProgress);<br />}<br />});<br />} catch (final Exception e) {<br />this.mException = e;<br />}<br />return null;<br />}<br />@Override<br />public void onProgressUpdate(final Integer... values) {<br />this.mPD.setProgress(values[0]);<br />}<br />@Override<br />public void onPostExecute(final T result) {<br />try {<br />this.mPD.dismiss();<br />} catch (final Exception e) {<br />Log.e("Error", e.getLocalizedMessage());<br />/* Nothing. */<br />}<br />if(this.isCancelled()) {<br />this.mException = new CancelledException();<br />}<br />if(this.mException == null) {<br />pCallback.onCallback(result);<br />} else {<br />if(pExceptionCallback == null) {<br />Log.e("Error", this.mException.getLocalizedMessage());<br />} else {<br />pExceptionCallback.onCallback(this.mException);<br />}<br />}<br />super.onPostExecute(result);<br />}<br />}.execute((Void[]) null);<br />}<br />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) {<br />final ProgressDialog pd = ProgressDialog.show(pContext, pContext.getString(pTitleResID), pContext.getString(pMessageResID));<br />pAsyncCallable.call(new Callback<T>() {<br />@Override<br />public void onCallback(final T result) {<br />try {<br />pd.dismiss();<br />} catch (final Exception e) {<br />Log.e("Error", e.getLocalizedMessage());<br />/* Nothing. */<br />}<br />pCallback.onCallback(result);<br />}<br />}, pExceptionCallback);<br />}</p><p>public static class CancelledException extends Exception {<br />private static final long serialVersionUID = -78123211381435595L;<br />}<br />}

 

public interface AsyncCallable<T> {<br />// ===========================================================<br />// Final Fields<br />// ===========================================================<br />// ===========================================================<br />// Methods<br />// ===========================================================<br />/**<br /> * Computes a result asynchronously, return values and exceptions are to be handled through the callbacks.<br /> * This method is expected to return almost immediately, after starting a {@link Thread} or similar.<br /> *<br /> * @return computed result<br /> * @throws Exception if unable to compute a result<br /> */<br />public void call(final Callback<T> pCallback, final Callback<Exception> pExceptionCallback);<br />}

 

public interface Callback<T> {<br />// ===========================================================<br />// Final Fields<br />// ===========================================================<br />// ===========================================================<br />// Methods<br />// ===========================================================<br />/**<br /> * 當載入完成後回調,載入完畢的事後處理<br /> */<br />public void onCallback(final T pCallbackValue);<br />}<br />

 

public interface IProgressListener {<br />// ===========================================================<br />// Constants<br />// ===========================================================<br />// ===========================================================<br />// Methods<br />// ===========================================================<br />/**<br /> * @param pProgress between 0 and 100.<br /> */<br />public void onProgressChanged(final int pProgress);<br />}

 

public interface IProgressListener {<br />// ===========================================================<br />// Constants<br />// ===========================================================<br />// ===========================================================<br />// Methods<br />// ===========================================================<br />/**<br /> * @param pProgress between 0 and 100.<br /> */<br />public void onProgressChanged(final int pProgress);<br />}

 

public class BaseActivity extends Activity {</p><p>/**<br /> *<br /> * @param <T> 模板參數,操作時要返回的內容<br /> * @param pCallable 需要非同步呼叫的操作<br /> * @param pCallback 回調<br /> */<br />protected <T> void doAsync(final Callable<T> pCallable, final Callback<T> pCallback) {<br />ActivityUtils.doAsync(this, null, "內容讀取中,請稍等...", pCallable, pCallback, null, false);<br />}</p><p>protected <T> void doAsync(final CharSequence pTitle, final CharSequence pMessage, final Callable<T> pCallable, final Callback<T> pCallback) {<br />ActivityUtils.doAsync(this, pTitle, pMessage, pCallable, pCallback, null, false);<br />}</p><p>/**<br /> * Performs a task in the background, showing a {@link ProgressDialog},<br /> * while the {@link Callable} is being processed.<br /> *<br /> * @param <T><br /> * @param pTitleResID<br /> * @param pMessageResID<br /> * @param pErrorMessageResID<br /> * @param pCallable<br /> * @param pCallback<br /> */<br />protected <T> void doAsync(final int pTitleResID, final int pMessageResID, final Callable<T> pCallable, final Callback<T> pCallback) {<br />this.doAsync(pTitleResID, pMessageResID, pCallable, pCallback, null);<br />}<br />/**<br /> * Performs a task in the background, showing a indeterminate {@link ProgressDialog},<br /> * while the {@link Callable} is being processed.<br /> *<br /> * @param <T><br /> * @param pTitleResID<br /> * @param pMessageResID<br /> * @param pErrorMessageResID<br /> * @param pCallable<br /> * @param pCallback<br /> * @param pExceptionCallback<br /> */<br />protected <T> void doAsync(final int pTitleResID, final int pMessageResID, final Callable<T> pCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {<br />ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pCallable, pCallback, pExceptionCallback);<br />}<br />/**<br /> * Performs a task in the background, showing a {@link ProgressDialog} with an ProgressBar,<br /> * while the {@link AsyncCallable} is being processed.<br /> *<br /> * @param <T><br /> * @param pTitleResID<br /> * @param pMessageResID<br /> * @param pErrorMessageResID<br /> * @param pAsyncCallable<br /> * @param pCallback<br /> */<br />protected <T> void doProgressAsync(final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback) {<br />this.doProgressAsync(pTitleResID, pCallable, pCallback, null);<br />}<br />/**<br /> * Performs a task in the background, showing a {@link ProgressDialog} with a ProgressBar,<br /> * while the {@link AsyncCallable} is being processed.<br /> *<br /> * @param <T><br /> * @param pTitleResID<br /> * @param pMessageResID<br /> * @param pErrorMessageResID<br /> * @param pAsyncCallable<br /> * @param pCallback<br /> * @param pExceptionCallback<br /> */<br />protected <T> void doProgressAsync(final int pTitleResID, final ProgressCallable<T> pCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {<br />ActivityUtils.doProgressAsync(this, pTitleResID, pCallable, pCallback, pExceptionCallback);<br />}<br />/**<br /> * Performs a task in the background, showing an indeterminate {@link ProgressDialog},<br /> * while the {@link AsyncCallable} is being processed.<br /> *<br /> * @param <T><br /> * @param pTitleResID<br /> * @param pMessageResID<br /> * @param pErrorMessageResID<br /> * @param pAsyncCallable<br /> * @param pCallback<br /> * @param pExceptionCallback<br /> */<br />protected <T> void doAsync(final int pTitleResID, final int pMessageResID, final AsyncCallable<T> pAsyncCallable, final Callback<T> pCallback, final Callback<Exception> pExceptionCallback) {<br />ActivityUtils.doAsync(this, pTitleResID, pMessageResID, pAsyncCallable, pCallback, pExceptionCallback);<br />}<br />}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.