Q: Android Dynamic response type Retroft hello i have Json response like this 
[
    {
        "question": "hhhhh",
        "question_answer": "hhhh ",
        "question_type": "question type",
        "questioner_age": "questioner age",
        "questioner_city": "questioner city",
        "questioner_country": "questioner country",
        "questioner_name": "questioner name",
        "questioner_sex": "questioner sex",
        "comments_allowed": "1",
        "question_id": "63",
        "question_date": "05/08/2017 - 19:33",
        "is_public": "1"
    },
    {
        "question": "hhhh !!",
        "question_answer": "hhhh",
        "question_type": [],
        "questioner_age": [],
        "questioner_city": [],
        "questioner_country": [],
        "questioner_name": "hhhhh",
        "questioner_sex": [],
        "comments_allowed": "1",
        "question_id": "57",
        "question_date": "04/30/2017 - 14:24",
        "is_public": "1"
    }
]

if the column is null will return as an array like this    "question_type": [],
if not will return as a string ! 
so i tried to get this response  on retrofit  but i failed and always got this error 

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 4 column 2 path $

after i searched in the internet i tried something like this but its not working !! 
    Gson gson = new Gson();
    String json = response.body().toString();


    if (json instanceof String)
    {

    MyQuestionModelString parseObject = gson.fromJson(json, MyQuestionModelString.class);
                apiCallResponse.onSuccess(parseObject,responseMessage);
            }else {
    MyQuestionModel parseObject = gson.fromJson(json, MyQuestionModel.class);
                apiCallResponse.onSuccess(parseObject,responseMessage);
            }

any help !
UPDATAE ! 
this is my model for this response and same error !!! 
public class MyQuestionModel {

    @SerializedName("question")
    @Expose
    private String question;
    @SerializedName("question_answer")
    @Expose
    private String questionAnswer;
    @SerializedName("question_type")
    @Expose
    private List<Object> questionType = null;
    @SerializedName("questioner_age")
    @Expose
    private List<Object> questionerAge = null;
    @SerializedName("questioner_city")
    @Expose
    private List<Object> questionerCity = null;
    @SerializedName("questioner_country")
    @Expose
    private List<Object> questionerCountry = null;
    @SerializedName("questioner_name")
    @Expose
    private String questionerName;
    @SerializedName("questioner_sex")
    @Expose
    private List<Object> questionerSex = null;
    @SerializedName("comments_allowed")
    @Expose
    private String commentsAllowed;
    @SerializedName("question_id")
    @Expose
    private String questionId;
    @SerializedName("question_date")
    @Expose
    private String questionDate;
    @SerializedName("is_public")
    @Expose
    private String isPublic;
}

My Main issue that how to define this field ! question_type
screen shot

A: You problem is 

ava.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 4 column 2 path $



*

*If your json code is [...],your return is JSONArray , you can use Gsonto parse it to List<Object> .

*If your json code is {...},your return is JSONObject , you can use Gsonto parse it to Object .
So you should use List<MyQuestionModel> to get parsed data .
Change MyQuestionModel to List<MyQuestionModel> in your call code .
Sample
Call<List<MyQuestionModel>> getData();

And my code for doing it .
JSONEntity for you json 
public class JSONEntity {

/**
 * question : hhhhh
 * question_answer : hhhh
 * question_type : question type
 * questioner_age : questioner age
 * questioner_city : questioner city
 * questioner_country : questioner country
 * questioner_name : questioner name
 * questioner_sex : questioner sex
 * comments_allowed : 1
 * question_id : 63
 * question_date : 05/08/2017 - 19:33
 * is_public : 1
 */

private String question;
private String question_answer;
private String question_type;
private String questioner_age;
private String questioner_city;
private String questioner_country;
private String questioner_name;
private String questioner_sex;
private String comments_allowed;
private String question_id;
private String question_date;
private String is_public;

public String getQuestion() {
    return question;
}

public void setQuestion(String question) {
    this.question = question;
}

public String getQuestion_answer() {
    return question_answer;
}

public void setQuestion_answer(String question_answer) {
    this.question_answer = question_answer;
}

public String getQuestion_type() {
    return question_type;
}

public void setQuestion_type(String question_type) {
    this.question_type = question_type;
}

public String getQuestioner_age() {
    return questioner_age;
}

public void setQuestioner_age(String questioner_age) {
    this.questioner_age = questioner_age;
}

public String getQuestioner_city() {
    return questioner_city;
}

public void setQuestioner_city(String questioner_city) {
    this.questioner_city = questioner_city;
}

public String getQuestioner_country() {
    return questioner_country;
}

public void setQuestioner_country(String questioner_country) {
    this.questioner_country = questioner_country;
}

public String getQuestioner_name() {
    return questioner_name;
}

public void setQuestioner_name(String questioner_name) {
    this.questioner_name = questioner_name;
}

public String getQuestioner_sex() {
    return questioner_sex;
}

public void setQuestioner_sex(String questioner_sex) {
    this.questioner_sex = questioner_sex;
}

public String getComments_allowed() {
    return comments_allowed;
}

public void setComments_allowed(String comments_allowed) {
    this.comments_allowed = comments_allowed;
}

public String getQuestion_id() {
    return question_id;
}

public void setQuestion_id(String question_id) {
    this.question_id = question_id;
}

public String getQuestion_date() {
    return question_date;
}

public void setQuestion_date(String question_date) {
    this.question_date = question_date;
}

public String getIs_public() {
    return is_public;
}

public void setIs_public(String is_public) {
    this.is_public = is_public;
}
}

And the code for parse it .
 Gson gson = new Gson();
 String jsonString = response.body().string();
 Type type = new TypeToken<List<JSONEntity>>() {
    }.getType();
 List<JSONEntity> datas = gson.fromJson(jsonString, type);

EDIT
If your response is JSONArray , you can try like this .
List<JSONEntity> datas = response.body();


A: Try to change your JSON   Structure
First Approach
To
If the column is null return "question_type": null,else show  "question_type": "value"
Instead 
If the column is null will return as an array like this "question_type": [], if not will return as a string!
Second Approach Without changing Json structure
Handling Dynamic JSON Using Gson
Try this: 
You have to use  deserialize to parse dynamic datatype in json
In the reponse pojo use object 
Ex:
    Call<Object> call = //your API call  ResponsePojo  instead use `Object`
    call.enqueue(new Callback<Object>() 
    {
        @Override
        public void onResponse(Response<Object> response, Retrofit retrofit)
        {

                try {
                    JSONArray jsonArray=new JSONArray(json);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        Gson gson = new GsonBuilder()
                                .registerTypeAdapter(ServerResponse.class, new ServerResponse.OptionsDeserilizer())
                                .create();
                        ServerResponse serverResponse=gson.fromJson(jsonArray.get(i).toString(), ServerResponse.class);
                        System.out.println(serverResponse);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }



        }

        @Override
        public void onFailure(Throwable t) 
        {
         ///Handle failure
        }
    });

Use this ServerResponsePojo with  JsonDeserializer
    import android.text.TextUtils;

    import com.google.gson.Gson;
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    import com.google.gson.JsonParseException;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    import com.google.gson.reflect.TypeToken;

    import java.lang.reflect.Type;

    public class ServerResponse {

        @SerializedName("question")
        @Expose
        private String question;
        @SerializedName("question_answer")
        @Expose
        private String questionAnswer;


        private String questionerName;

        @SerializedName("comments_allowed")
        @Expose
        private String commentsAllowed;
        @SerializedName("question_id")
        @Expose
        private String questionId;
        @SerializedName("question_date")
        @Expose
        private String questionDate;
        @SerializedName("is_public")
        @Expose
        private String isPublic;

        public String getQuestion() {
            return question;
        }

        public void setQuestion(String question) {
            this.question = question;
        }

        public String getQuestionAnswer() {
            return questionAnswer;
        }

        public void setQuestionAnswer(String questionAnswer) {
            this.questionAnswer = questionAnswer;
        }


        /* public List<OptionValue> getQuestionerAge() {
             return questionerAge;
         }

         public void setQuestionerAge(List<OptionValue> questionerAge) {
             this.questionerAge = questionerAge;
         }

         public List<OptionValue> getQuestionerCity() {
             return questionerCity;
         }

         public void setQuestionerCity(List<OptionValue> questionerCity) {
             this.questionerCity = questionerCity;
         }

         public List<OptionValue> getQuestionerCountry() {
             return questionerCountry;
         }

         public void setQuestionerCountry(List<OptionValue> questionerCountry) {
             this.questionerCountry = questionerCountry;
         }
     */
        public String getQuestionerName() {
            return questionerName;
        }

        public void setQuestionerName(String questionerName) {
            this.questionerName = questionerName;
        }
    /*
        public List<OptionValue> getQuestionerSex() {
            return questionerSex;
        }

        public void setQuestionerSex(List<OptionValue> questionerSex) {
            this.questionerSex = questionerSex;
        }*/

        public String getCommentsAllowed() {
            return commentsAllowed;
        }

        public void setCommentsAllowed(String commentsAllowed) {
            this.commentsAllowed = commentsAllowed;
        }

        public String getQuestionId() {
            return questionId;
        }

        public void setQuestionId(String questionId) {
            this.questionId = questionId;
        }

        public String getQuestionDate() {
            return questionDate;
        }

        public void setQuestionDate(String questionDate) {
            this.questionDate = questionDate;
        }

        public String getIsPublic() {
            return isPublic;
        }

        public void setIsPublic(String isPublic) {
            this.isPublic = isPublic;
        }

        public class OptionValue {

        }

        public void setQuestionType(String questionType) {
            this.questionType = questionType;
        }

        String questionType;


        public static class OptionsDeserilizer implements JsonDeserializer<ServerResponse> {

            @Override
            public ServerResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                Type listType = new TypeToken<ServerResponse>() {
                }.getType();
                ServerResponse options = (ServerResponse) new Gson().fromJson(json, listType);

                JsonObject jsonArrayValue = json.getAsJsonObject();

                for (int i = 0; i < jsonArrayValue.size(); i++) {
                    JsonObject jsonObject = jsonArrayValue.getAsJsonObject();
                    if (jsonObject.has("question_type")) {
                        JsonElement elem = (JsonElement) jsonObject.get("question_type");
                        if (elem != null && !elem.isJsonNull() && !elem.isJsonArray()) {
                            String valuesString = elem.getAsString();
                            if (!TextUtils.isEmpty(valuesString)) {
                                options.setQuestionType(valuesString);
                            } else {
                                options.setQuestionType("");
                            }

                            //Do your other stuffs
                        }
                    }

                }


                return options;
            }
        }

    }

This is working happy codeing

A: During the parsing of json if the SerializedName key is not found it will throw an exception. Use @Expose to let the deserializer to know that this field can be null. Here is a similar Model of your mentioned response
public class ResponsePojo {

List<Data> data;

public class Data {
    @Expose
    @SerializedName("question")
    String question;

    @Expose
    @SerializedName("question_answer")
    String questionAnswer;

    @Expose
    @SerializedName("question_type")
    String questionType;

    @Expose
    @SerializedName("questioner_age")
    String questionerAge;

    @Expose
    @SerializedName("questioner_city")
    String questionerCity;

    @Expose
    @SerializedName("questioner_country")
    String questionerCountry;

    @Expose
    @SerializedName("questioner_name")
    String questionerName;

    @Expose
    @SerializedName("questioner_sex")
    String questionerSex;

    @Expose
    @SerializedName("comments_allowed")
    String commentsAllowed;

    @Expose
    @SerializedName("question_id")
    String questionId;

    @Expose
    @SerializedName("question_date")
    String questionDate;

    @Expose
    @SerializedName("is_public")
    String isPublic;
}

}

A: You must indicate which paramters or objects in the model are optional with @Exposed tag.
Example
    @Expose
    @SerializedName("question_type")
    private String mQuestionType;

