前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >android异步操作

android异步操作

作者头像
xiangzhihong
发布2018-01-29 10:43:04
7770
发布2018-01-29 10:43:04
举报
文章被收录于专栏:向治洪向治洪向治洪

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

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

clip_image001
clip_image001

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

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引擎的实现代码进行的修改。

附源码:

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;  
    }  
}  
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 {@link 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);  
}  
public interface Callback<T> {  
 // =========================================================== 
 // Final Fields 
 // =========================================================== 
 // =========================================================== 
 // Methods 
 // =========================================================== 
 /** 
     * 当加载完成后回调,加载完毕的事后处理   
     */ 
 public void onCallback(final T pCallbackValue);  
}  
public interface IProgressListener {  
 // =========================================================== 
 // Constants 
 // =========================================================== 
 // =========================================================== 
 // Methods 
 // =========================================================== 
 /** 
     * @param pProgress between 0 and 100. 
     */ 
 public void onProgressChanged(final int pProgress);  
}  
public interface IProgressListener {  
 // =========================================================== 
 // Constants 
 // =========================================================== 
 // =========================================================== 
 // Methods 
 // =========================================================== 
 /** 
     * @param pProgress between 0 and 100. 
     */ 
 public void onProgressChanged(final int pProgress);  
}  
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 {@link ProgressDialog}, 
     * while the {@link 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 {@link ProgressDialog}, 
     * while the {@link 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 {@link ProgressDialog} with an ProgressBar, 
     * while the {@link 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 {@link ProgressDialog} with a ProgressBar, 
     * while the {@link 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 {@link ProgressDialog}, 
     * while the {@link 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);  
    }  
}  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-01-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档