我已经开发了许多发出 Web 服务请求的 Android 应用程序,始终采用以下方法:
在每个需要发出 Web 服务请求的 Activity 中,我定义了一个内部 AsyncTask
,它在 onPreExecute()
中显示一个 ProgressDialog
,在 doInBackground
中调用 Web 服务,关闭 progressDialog 并通过 onPostExecute()
更新 UI 中的结果。
我担心的是:是否有更好(更短)的方法来做到这一点?在每个 Activity 中重复所有代码是否有意义?我一直在谷歌上搜索,但我一无所获。
我的问题是:我不能定义一个回调接口(interface)吗?例如这个:
public interface RequestCallback {
public void onSuccess(Whatever whatever);
public void onError(ErrorCode errorCode, String message);
}
... 然后定义一个外部类,例如 AsyncRequest
,它包装了 AsyncTask 定义和 ProgressDialog show()
和 dismiss()
语句。因此,所有 Activity 只需要实例化该类,并传入以下参数:
1) web服务运行的方法
2) 包含该 Web 服务方法的所有参数的 Bundle
3) RequestCallback 实例(可以是匿名内联实例,我可以在其中从 onSuccess()
更新 UI)
4) Activity 的上下文(显示 ProgressDialog() 所必需的,所以我仍然需要一种方法来防止配置更改异常等等...),
你觉得这个设计好吗?它可以节省数百行代码...
最佳答案
您的方法就是我在我的项目中所做的。正如你所说,它节省了很多代码,我对此没有任何提示。但是这里有一些问题我想告诉你:
- 您应该在每次执行后台线程时创建新的
AsyncTask
实例,以避免堆积回调。 对于进度对话框,我将其用作
Singleton
,因为您不会同时显示多个对话框。该对话框将在您调用后台作业时显示,并将在回调中关闭。这是我所做的:private void showProgressDialog(String strMess){ if(null == progressDialog){ progressDialog = new ProgressDialog(MainActivity.this); } if(!progressDialog.isShowing()){ progressDialog.setMessage(strMess); progressDialog.show(); } } private void hideProgressDialog(){ if(null != progressDialog && progressDialog.isShowing()){ progressDialog.dismiss(); } } void someMethod(){ showProgressDialog("Loading..."); doBackgroundJob(param, new RequestCallBack() { public void onRequestCompleted(String message, boolean isSuccess) { hideProgressDialog(); if(isSuccess){ }else{ //do something on error } } }); }
它是一个可选的,我定义了一个接口(interface)来通知而不是特定的类,对于每个响应我使用一个类,所以在基类中,我不关心响应是什么。这是它:
public interface OnRequestCompleted<TResponse> { void requestCompleted(TResponse response); } public abstract class BaseRequest<TResponse> implements IRequest{ protected OnRequestCompleted<TResponse> delegate; protected Class<TResponse> responseClass; @Override public void send() { new HttpTask().execute(); } private class HttpTask extends AsyncTask<Void, Void, String> { //... @Override protected void onPostExecute(String result) { if (null != response && null != delegate) { delegate.requestCompleted(response); } } } // the response example public class GroupResponse { public static class Clip { public int clipId; public String detail; } public static class Movie { public int movieId; public String detail; } }
在
BaseRequest
的子类中,我会准确地告诉它响应类是什么(Movie、Clip...)
希望这对您有所帮助。
关于android - 带回调的通用 asyncTask(用于 Web 服务),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14347093/