做过Android手机开发的人都知道,手机UI是一个单独的线程在运行,并且该线程最好不会因为用户的操作而阻塞。换句话说,如果用户进行的操作需要耗时几十秒甚至几十分钟,那么在这段时间内占用UI线程是一个非常不明智的做法。它会阻塞掉UI线程,导致手机不再显示或者接受用户新的操作,给用户一种死机的感觉。

因此最好的方法是将用户耗时较长的操作放到另一个线程中去,并且用监听者模式来监听操作的完成。比如,手机服务通过http协议与服务器建立通讯,为了使此通讯不会阻塞手机其他功能的显示,需要开辟一个新线程传输数据,一旦数据传输完毕,则会调用监听者的回调函数,将结果显示在手机屏幕上。本文将介绍一种UI和耗时操作分离的方法:

每个复杂操作我们需要将其抽象成一个Task:

//定义一个BaseTask基类,其中taskParameter是需要执行任务所要传递的参数//而execute()函数将在派生类中被重写public abstract class BaseTask {Object  taskParameter; abstract Object execute() throws Exception;}在基类基础上,定义派生类:public class AsynMethodTask extends BaseTask {public AsynMethodTask(AsynMethodTaskParameter taskParameter) {this.taskParameter = taskParameter;}//重写execute函数,这里利用了Java提供的Method类,instance是需要执行的类,而methodName是需要执行的方法,methodParameter是需要传递的参数@Overridepublic Object execute() throws Exception {AsynMethodTaskParameter parameters = (AsynMethodTaskParameter) this.taskParameter;Method method = MethodHelper.getMethod(parameters.instance,parameters.methodName, parameters.methodParameters);if (method != null) {return method.invoke(parameters.instance,parameters.methodParameters);}return null;}//工厂模式,返回一个Task的实例public static AsynMethodTask CreateTask(Object instance, String methodName,Object... parameters) {return new AsynMethodTask(new AsynMethodTaskParameter(instance,methodName, parameters));}}


AsynMethodTaskParameter定义如下:

public class AsynMethodTaskParameter{ public Object instance; public String methodName; public Object[] methodParameters; public AsynMethodTaskParameter (Object instance , String methodName,Object[] methodParameters ) { this.instance = instance; this.methodName = methodName; this.methodParameters = methodParameters; }}


这样,一个基本的TASK方法已经实现,那么如何使用它呢?我们需要一个Request类来发送请求,并且异步启用task:

public class Request extends AsyncTask<RequestParameter, Integer, Object> {private RequestListener emmaRequestListener = null;private Object data = null;private Exception _errorException = null;//在后台异步启动TASK,AsyncTask提供了异步功能,需要重载其中的回调函数@Overrideprotected Object doInBackground(RequestParameter... parameter) {try {RequestParameter emmaRequestParameter = parameter[0];emmaRequestListener = emmaRequestParameter.requestListener;data = emmaRequestParameter.data;BaseTask task = emmaRequestParameter.task;return task.execute();}catch (InvocationTargetException e) {Throwable baseException = e.getCause() ;if (baseException == null)_errorException = new LocalGeneralException(e.getMessage());else {if (baseException instanceof ServerGeneralException){_errorException = new ServerGeneralException(baseException.getMessage());}else if (baseException instanceof ServerAuthException){_errorException = new ServerAuthException(baseException.getMessage());}else {_errorException = new LocalGeneralException(baseException.getMessage());}}}catch (Exception e) {_errorException = new LocalGeneralException(e.getMessage());}return _errorException;}//执行结束后,如果没有异常,则调用回调函数@Overrideprotected void onPostExecute(Object result) {if (_errorException == null) {emmaRequestListener.onRequestSuccess(result, data);} else {emmaRequestListener.onRequestFailed(_errorException, data);}}//中途如果被cancel掉@Overrideprotected void onCancelled() {emmaRequestListener.onRequestCanceled(data);}public interface RequestListener {void onRequestSuccess(Object result, Object data);void onRequestFailed(Object result, Object data);//void onRequestCanceled(Object data);}//定义执行过程,需要加入task,如果成功会调用RequestListener所定义的函数public static Request executeAsynRequest(BaseTask task,RequestListener requestListener, Object data) {RequestParameter requestParameter = new RequestParameter(task,requestListener, data);Request r = new Request();r.execute(requestParameter);return r;}}


最后我们只需要定义好Method的名字:

public final static class Methods{public static String getProfileView = "getProfileView";public static String uploadProfileView = "uploadProfileView";public static String getUserProfile = "getUserProfile";        }


就可以正常调用了:

AsynMethodTask task = AsynMethodTask.CreateTask(profileModel, ProfileModel.Methods.uploadProfileView, profileUploadData);Request.executeAsynRequest(task, this, TASK_UPLOAD_PROFILE);


整个过程相当简单,最重要的是熟悉观察者模式,以及AsyncTask类的运行方式,重载其中的回调函数,让我们的任务在后台运行。返回的值为Object对象,需要通过强制类型转换成为我们需要的值。而传递进去的参数可以通过无限制数目的参数传递。

更多相关文章

  1. Android里面如何编写退出主程序的提示代码
  2. Android(安卓)Native 程序逆向入门(一)—— Native 程序的启动流程
  3. 关于android多任务同时下载的一点心得
  4. Android10 insmod源码分析
  5. android input命令 模拟按键
  6. android数据库操作之直接读取db文件
  7. 使用Android(安卓)AsyncTask异步线程
  8. Android模拟器常用操作
  9. Netty 之Oio程序编写

随机推荐

  1. android查看网络图片的实现方法
  2. android 实现分享功能
  3. android adb命令打印logcat日志 到指定目
  4. 如何获取 android 的系统日志 logcat
  5. 利用Android(安卓)Studio将Protobuf文件
  6. android support-v4、v7、v13
  7. widget
  8. android .mk 引用第三方jar包(参考 Calcul
  9. iOS Android(安卓)WebView 通过 Cookie
  10. android中联系人以及 ContactsContract类