0
public class ResponseData<T>
{
    @SerializedName("status")
    private String mStatus;
    @SerializedName("description")
    private String mDescription;
    @SerializedName("data")
    private ArrayList<T> mData;
    @SerializedName("error_code")
    private int mErrorCode;

    public String getStatus() {return mStatus;}
    public String getDescription() { return mDescription;}
    public ArrayList<T> getData() { return mData; }
}

//common fields go here

public class BaseData {}

//user feilds go here

public class UserData extends BaseData {}

//some location fields go here

public class LocationData extends BaseData {}

//Json Deserializer

public class JsonDeserializer
{
    public static String toJson(Object t)
    {
        return new Gson().toJson(t);
    }

    public static <T> T fromInputStream(InputStream inputStream, Class<T> clz)
    {
        Reader reader = new InputStreamReader(inputStream);
        return new Gson().fromJson(reader, clz);
    }
}


public class HttpRequester
{
    public enum RequestType {GET, POST, DELETE, PUT};

    public void makeRequest(RequestType requestType, BaseData baseData, String path)
    {

        //submit data to api
        //the api then returns a response
        // baseData.getClass(); //this can either be UserData or LocationData

        HttpEntity entity = response.getEntity();

        //I am getting stuck here. I want the responseData mData field to be the same type as the baseData I am sending to the api.

        //this is not valid syntax
        ResponseData response = JsonDeserializer.fromInputStream(entity.getContent(), ResponseData<baseData.getClass()>.class );

    }
}

Here is some sample json

{"data":[{"username":"james","email":"james@gmail.com","height":72.0,"phone":"+15555555555"}], "error_code": 0, "description":null }

{"data":[{"latidue":40.022022,"longitude":-29.23939, "street":"union ave", "borough":"manhattan"}', "error_code": 0, "description":null }

The JsonDeserializer should return either ResponseData with mData being an arraylist of type LocationData or ResponseData with mData being an arrayList of of type UserData.

James
  • 9,694
  • 5
  • 32
  • 38

1 Answers1

1

First, don't use raw types.

Second, You'll need to use type tokens. A TypeToken is a pseudo-hack to get around some of the limitations of type erasure.

You'll need to create a type token

TypeToken token = new TypeToken<ResponseDate<LocationData>>() {};

And then feed the TypeToken's represented type to Gson (don't recreate a new Gson object every time, save and use the one instance)

gson.fromGson(reader, token.getType());

You'll need to have a TypeToken for each parametrized version of ResponseData<..>.

Related:

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Thank you for pointing me in the right direction. I knew I had to use TypeToken the only problem was I trying to figure out how to get the type token on during runtime. I was able to solve by using the factory pattern. The ResponseData could either be location or user data. So I created a token factory that returns either a new TypeToken>() {}; or new TypeToken>() {}; and passed it to the JsonDeserializer.fromInputStream – James Jun 24 '14 at 14:03