#android #json #android-asynctask #gson #retrofit2
#Android #json #android-asynctask #gson #retrofit2
Вопрос:
Я просто новичок в json и модернизации и хочу получить файл json с сервера в свой список.
У меня есть класс вопросов
public class Question {
private String label;
private ArrayList<String> question;
public Question(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
public void setQuestion(ArrayList<String> question) {
this.question = question;
}
public ArrayList<String> getQuestion() {
return question;
}
@Override
public String toString() {
String s = "Label: " label;
for (String t : question) {
s = "n" t;
}
return s;
}
}
Я использую Retrofit2 для настройки Api для получения объекта
public interface ServiceApi {
@GET("/bins/{id}?pretty=1")
Call<Object> getJson(@Path("id") String id);
}
Вот моя задача данных, которая реализует интерфейс
public class DataTask {
private static final String API_BASE_URL = "https://api.myjson.com";
private static final String TAG = "DataTask";
private static ServiceApi serviceApi;
public DataTask() {
createApi();
}
private void createApi() {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.client(httpClient.build()).build();
serviceApi = retrofit.create(ServiceApi.class);
}
public static String getJson(String id) {
String t = null;
Call<Object> response = serviceApi.getJson(id);
try {
t = response.execute().body().toString();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
Log.d(TAG, "GET Success: " t);
return t;
}
}
Вот моя основная особенность
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final List<Question>[] questions = new List[1];
final String[] s = new String[1];
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
new DataTask();
s[0] = DataTask.getJson("2yf1q");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
questions[0] = new Gson().fromJson(s[0], new TypeToken<List<Question>>() {
}.getType());
Log.d(TAG, String.valueOf(questions[0].toString()));
for (Question q : questions[0]) {
Log.d(TAG, q.toString());
}
}
}.execute();
}
}
И вот моя ссылка Json https://api.myjson.com/bins/2yf1q?pretty=1
При запуске я получил это исключение
com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated array at line 1 column 30 path $[0].question[1]
at com.google.gson.Gson.fromJson(Gson.java:902)
at com.google.gson.Gson.fromJson(Gson.java:852)
at com.google.gson.Gson.fromJson(Gson.java:801)
at svmc.anthao.MainActivity$1.onPostExecute(MainActivity.java:49)
at svmc.anthao.MainActivity$1.onPostExecute(MainActivity.java:36)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5268)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(Native Method)
Я не понимаю, как это может быть.
Пожалуйста, помогите мне исправить это, большое вам спасибо
Комментарии:
1. Попробуйте создать возвращаемый тип вашего модифицированного вызова<Вопрос>
2. спасибо @FilipeEsperandio за ответ, я пытался, но получил то же исключение
Ответ №1:
Пришлось поиграть с вашим API, чтобы реализовать это. Конечная точка возвращает массив, а не объект, поэтому ваш модифицированный интерфейс должен быть:
@GET("/bins/{id}?pretty=1")
Call<List<Question>> getJson(@Path("id") String id);
Вот рабочий пример:
public class SampleTest {
public class Question {
private String label;
private ArrayList<String> question;
public Question(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
public void setQuestion(ArrayList<String> question) {
this.question = question;
}
public ArrayList<String> getQuestion() {
return question;
}
@Override
public String toString() {
String s = "Label: " label;
for (String t : question) {
s = "n" t;
}
return s;
}
}
public interface ServiceApi {
@GET("/bins/{id}?pretty=1")
Call<List<Question>> getJson(@Path("id") String id);
}
private static final String API_BASE_URL = "https://api.myjson.com";
@Test
public void restCall() throws Exception {
OkHttpClient httpClient = new OkHttpClient();
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.client(httpClient).build();
ServiceApi serviceApi = retrofit.create(ServiceApi.class);
Call<List<Question>> call = serviceApi.getJson("2yf1q");
List<Question> questions = call.execute().body();
assertThat(questions, notNullValue());
}
}