从 AsyncTask 返回多个数据



我正在尝试组织我的应用程序代码,将 AsyncTask 类与活动或片段分开。浏览这个论坛,我了解了"接口和侦听器"解决方案:

界面.java

public interface TaskCompleteListener<T> {
    public void onTaskComplete(T result);
}

异步任务.java

[...]
@Override
protected void onPostExecute(String JSONResponse) {
    // using Gson library I convert JSONResponse string to POJO objects...
    listener.onTaskComplete(result);
}

活动.java

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    // start AsyncTask...
    }
    // Inner class implementing interface
    public class LoadTaskCompleteListener implements TaskCompleteListener<Object> {
        @Override
        public void onTaskComplete(Object result) {
            updateUI(result);
        }
    }
    public void updateUI(Object result) {
    // here you can manage UI updating, using result object
    }
}

更新数据助手.java

public class DataHelper {
    private AsyncTaskCompleteListener<Object> listener;
    public DataHelper(AsyncTaskCompleteListener<Obejct> listener) {
        this.listener = listener;
    }
    // Multiple AsyncTask are defined here...
}

好吧,我非常喜欢这种模式,但是:如果内部活动(或片段)怎么办我有多个请求,具有不同类型的结果(单个对象、数组、列表)以及用于管理它们的不同业务逻辑?我无法使用单个回调来处理这个问题。有什么想法吗?我应该添加多个接口内的回调?我真的被这个困住了。我有一个叫做DataHelper的文件,里面有多个AsyncTask(类似于Web getters)。当然,如果您提出任何其他选择,我可以放弃这种方法。

为什么不返回一个对象数组作为结果?然后,如果该数组中有多个对象,您将知道放置它们的顺序,以便一次可以使用多组结果。

public interface TaskCompleteListener<T> {
    public void onTaskComplete(T... results);
}

请注意,可以使用"处理程序"代替异步任务,并且每个处理程序都可以将其消息返回到消息循环器,而 msg 包装不同的数据。易于处理许多数据类型,因为它只是一个消息组件。 在这里采样

请参阅"process_entity()",其中包含结果组件的消息通过示例代码发送。

请注意,onTaskComplete()的定义接受泛型类型作为参数,类型 T

 onTaskComplete(T result);

这意味着您可以传入任何对象类型、单个对象、数组、列表等。

关于如何使用单个回调处理不同的结果,您可以使用Bundle将结果放入,与密钥相关联,然后在updateUI()检查该密钥并采取适当的操作。

像这样的东西(伪代码,不确定它是否会编译):

@Override
protected void onPostExecute(String JSONResponse) {
    Bundle bundle = new Bundle();
    bundle.putString("key_json_response", result); //put the response in a Bundle
    listener.onTaskComplete(bundle);
}
// .....
public void updateUI(Object result) {
   Bundle bundle = (Bundle)result;
   if(bundle.containsKey("key_json_response")){
     String json = bundle.getString("key_json_response");
     // process json
   } else if(bundle.containsKey("key_another_response")){
     // process another response
   } 
}

最新更新