Java 如何在Android中通过Asynctask返回不同的对象

Java 如何在Android中通过Asynctask返回不同的对象,java,android,json,android-asynctask,return-type,Java,Android,Json,Android Asynctask,Return Type,我想这一定是一个常见的问题,但令人惊讶的是我找不到答案,所以可能我的整个结构很糟糕 我有一个活动,通过AsyncTask从web服务下载游戏的值/状态。这些值用于更新自定义视图 创建视图后,视图中的各种事件将启动AsyncTask以下载其他信息 这是功能性的,但问题是我现在在活动中有六个AsyncTask类,代码几乎相同。唯一的区别是返回的对象类型(基于web服务的json)和从onPostExecute()调用的方法 在不知道web服务将返回何种类型的json对象的情况下,如何仅使用两个Asy

我想这一定是一个常见的问题,但令人惊讶的是我找不到答案,所以可能我的整个结构很糟糕

我有一个活动,通过AsyncTask从web服务下载游戏的值/状态。这些值用于更新自定义视图

创建视图后,视图中的各种事件将启动AsyncTask以下载其他信息

这是功能性的,但问题是我现在在活动中有六个AsyncTask类,代码几乎相同。唯一的区别是返回的对象类型(基于web服务的json)和从
onPostExecute()
调用的方法

在不知道web服务将返回何种类型的json对象的情况下,如何仅使用两个AsyncTask(一个用于post,一个用于get)

同样,如何确定web服务返回的对象的类型?如果出现问题,web服务将返回与ErrorMessage对象相关的json字符串,而不是(例如)GameData对象


我是否应该在
onPostExecute()
中使用
switch
instanceof
?回调可能吗?

您可以使用一个抽象基类,您的相关类可以扩展它

示例代码:

public abstract class IBaseObject {
    protected String error;

    public IBaseObject(String param) {
        error = param;
    }

    public abstract String getError();
}

public class ObjectOne extends IBaseObject {        
    private String objectParam;        

    public ObjectOne(String error, String objectSpecificParam) {
        super(error);
        objectParam = objectSpecificParam;
    }

    @Override
    public String getError() {
        return error;
    }
}
例如,像这样使用它:

private class GetTask extends AsyncTask<String, Void, IBaseObject> {
    protected IBaseObject doInBackground(String... url) {
        // Get your data.
        // Construct your corresponding object given by specific
        // parameters from your JSON response.
        if (a_parameter_match) {
            return new ObjectOne(some_json_params...);
        } else {
            return new ObjectTwo(some_json_params...);
        }        
    }    

    protected void onPostExecute(IBaseObject object) {
        object.getError(); // Or whatever you need here.
    }
} 
私有类GetTask扩展了异步任务{
受保护的IBaseObject doInBackground(字符串…url){
//获取您的数据。
//构造特定对象给定的对应对象
//JSON响应中的参数。
if(参数匹配){
返回新的ObjectOne(一些参数;
}否则{
返回新的ObjectTwo(一些参数…);
}        
}    
受保护的void onPostExecute(IBaseObject对象){
object.getError();//或此处需要的任何内容。
}
} 

这是我的第一印象。我无法解释你的具体问题,尽管这里的想法应该足以让你开始新的结构。

这太长了,无法发表评论,所以我正在写一个答案。然而,正是@Pompe de velo的建议让我走上了这条轨道,所以我接受了这个答案。我还从我的问题中遗漏了一些可能有用的信息

无论如何,到目前为止,我看不出这种方法有任何主要的缺点,但是时间(或者其他用户;])会告诉我

本质上,我已经为活动将尝试获取的每种类型的对象指定了一个常量。我遗漏的部分是,服务器仅返回4xx-5xx http状态码上的错误对象。换句话说,我肯定会得到我期望的对象或错误对象,并且我可以确定从状态代码中得到了哪个。然后,
开关
将实际的json字符串发送到适当的方法,该方法可以根据需要操纵响应

简化伪代码

private void getGameData(){
    new MyAsyncTask(this, MyAsyncTask.OBJ_GAME_DATA).execute();
}

static class MyAsyncTask extends AsyncTask<String, Integer, String> {
    private int outputObjectType;

    protected static final int OBJ_GAME_DATA = 0;
    protected static final int OBJ_OTHER_DATA = 1;
    protected static final int OBJ_DIFFERENT_DATA = 2;
    protected static final int OBJ_SERVER_ERROR = 3;

    MyAsyncTask(MyActivity activity, int expectedObject){
        outputObjectType = expectedObject;
    }

    doInBackground(){
        if(httpStatusCode >= 400){
             outputObjectType = MyAsyncTask.OBJ_SERVER_ERROR;
        }

        return jsonStringFromServer;
    }

    onPostExecute(String json){
        switch(outputObjectType){
        case MyAsyncTask.OBJ_SERVER_ERROR:
            serverError(json);
            break;
        case MyAsyncTask.OBJ_GAME_DATA:
            processGameData(json);
            break;
        // ....
        }
    }
}

private void serverError(String json){
    ServerError se = new Gson().fromJson(json, ServerError.class);
    Log.d(TAG, se.getErrorMessage());
}

private void processGameData(String json){
    GameData gd = new Gson().fromJson(json, GameData.class);
    // .......
}
private void getGameData(){
新建MyAsyncTask(这是MyAsyncTask.OBJ_GAME_DATA).execute();
}
静态类MyAsyncTask扩展了AsyncTask{
私有int输出对象类型;
受保护的静态最终int OBJ_游戏数据=0;
受保护的静态最终int OBJ_其他_数据=1;
受保护的静态最终int OBJ_不同数据=2;
受保护的静态最终int OBJ_服务器错误=3;
MyAsyncTask(MyActivity活动,int-expectedObject){
OutputObject类型=expectedObject;
}
doInBackground(){
如果(httpStatusCode>=400){
outputObjectType=MyAsyncTask.OBJ_服务器错误;
}
返回jsonStringFromServer;
}
onPostExecute(字符串json){
开关(输出对象类型){
案例MyAsyncTask.OBJ_服务器错误:
serverError(json);
打破
案例MyAsyncTask.OBJ_游戏数据:
processGameData(json);
打破
// ....
}
}
}
私有void服务器错误(字符串json){
ServerError se=new Gson().fromJson(json,ServerError.class);
Log.d(标记,se.getErrorMessage());
}
私有void processGameData(字符串json){
GameData gd=new Gson().fromJson(json,GameData.class);
// .......
}
我认为这并不是@Pompe de velo所说的,但是我只是基于状态代码而不是json中的某个内容,使我的
参数匹配


如果这是有缺陷的,我想知道为什么

switch和instanceof通常会起作用。有时,当我需要向列表中添加不同类型的对象时,我会声明一个所有类都需要实现的接口(某种标记接口)。因此,您可以添加类似的内容,并让AsyncTask始终返回指定的类型。谢谢!这个前提让我找到了我需要去的地方。