Android 中UI与耗时操作的分离

做过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);少一点预设的期待,那份对人的关怀会更自在

Android 中UI与耗时操作的分离

相关文章:

你感兴趣的文章:

标签云: