android - 带回调的通用 asyncTask(用于 Web 服务)

标签 android web-services android-asynctask

我已经开发了许多发出 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() 所必需的,所以我仍然需要一种方法来防止配置更改异常等等...),

你觉得这个设计好吗?它可以节省数百行代码...

最佳答案

您的方法就是我在我的项目中所做的。正如你所说,它节省了很多代码,我对此没有任何提示。但是这里有一些问题我想告诉你:

  1. 您应该在每次执行后台线程时创建新的 AsyncTask 实例,以避免堆积回调。
  2. 对于进度对话框,我将其用作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
                }
            }
        });
    
      }
    
  3. 它是一个可选的,我定义了一个接口(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/

相关文章:

android - 如何在 Android 中集成 Twitter 关注按钮?

java - RxJava中对buffer的错误理解

java - 如何在 Java Android Spring 中接收验证错误

android - 无法构建来自 AsyncTask 的进度对话框的更新进度

android - 将图像加载异步任务转换为 rxjava,为什么它滞后于 ui?

android - 在上传到 Google Play 商店之前如何实现共享应用程序?

android - 删除 RecyclerView FooterView

java - 使用 Web 服务部署 Web 应用程序后出现错误 "java.lang.NoSuchMethodError"

c# - 从一台电脑复制到另一台电脑后,WebService (.asmx) 功能未显示

java - 了解 REST API——什么是 Context 和 @Context?