Невозможно вызвать API пользователя поиска GItHub с помощью Retrofit - PullRequest
0 голосов
/ 08 мая 2020

Я экспериментирую с API пользователей поиска GitHub . Моя цель - написать простое приложение: введите имя пользователя, и любое имя пользователя GitHub, связанное с ним, будет отображаться в RecyclerView (с использованием шаблона MVVM).

Например, вот как найти имя пользователя clive :

https://api.github.com/search/users?q=clive

А вот соответствующие части кода:

APIConfig. java

public class APIConfig {

    public static final String BASE_URL = "https://api.github.com";
    public static final String END_POINT_SEARCH_USERS = "/search/users";

}

APIEndPoint. java

import com.divbyzero.app.githubusersearch.model.User;

import java.util.List;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface APIEndPoint {

    @GET(APIConfig.END_POINT_SEARCH_USERS)
    Call<List<User>> getSearchResult(@Query("q") String param);

}

Пользователь. java

    package com.divbyzero.app.githubusersearch.model;

    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;

    public class User {

        @SerializedName("login")
        @Expose
        private String login;

        @SerializedName("avatar_url")
        @Expose
        private String avatar_url;

        public void setLogin(String login){
            this.login = login;
        }

        public void setAvatarUrl(String url){
            this.avatar_url = url;
        }

        public String getLogin(){
            return login;
        }

        public String getAvatarUrl(){
            return avatar_url;
        }

        public User(String login, String url){
            this.login = login;
            this.avatar_url = url;
        }
    }

UserViewModel. java

  package com.divbyzero.app.githubusersearch.viewmodel;

    import android.util.Log;

    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.MutableLiveData;
    import androidx.lifecycle.ViewModel;

    import com.divbyzero.app.githubusersearch.api.APIEndPoint;
    import com.divbyzero.app.githubusersearch.api.APIService;
    import com.divbyzero.app.githubusersearch.model.User;

    import java.util.ArrayList;
    import java.util.List;

    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    import retrofit2.Retrofit;

    public class UserViewModel extends ViewModel {

        private MutableLiveData<ArrayList<User>> mutableLiveData = new MutableLiveData<>();

        public void setSearchResult(String param){
            Retrofit retrofit = APIService.getRetrofitService();
            APIEndPoint apiEndpoint = retrofit.create(APIEndPoint.class);
            Call<List<User>> call = apiEndpoint.getSearchResult(param);
            call.enqueue(new Callback<List<User>>() {
                @Override
                public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                    mutableLiveData.setValue((ArrayList<User>) response.body());
                    Log.d("DBG", "OK");
                }

                @Override
                public void onFailure(Call<List<User>> call, Throwable t) {
                    Log.d("DBG", "Failed");
                }
            });
        }

        public LiveData<ArrayList<User>> getSearchResult(){
            return mutableLiveData;
        }
    }

Полный исходный код: https://github.com/anta40/GithubUserSearch

Когда я ввожу любое имя пользователя в SearchView и нажимаю клавишу ENTER, результаты поиска не отображаются (Reclerview все еще пуст) . После дополнительной проверки я обнаружил, что в logcat отображается сообщение «DBG: Failed», что означает, что API GitHub не был вызван должным образом. Как это исправить?

1 Ответ

1 голос
/ 08 мая 2020

Ошибка

Ошибка, которая появляется в вашей модели представления:

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

Итак, возникла проблема с анализом вашего ответа. Вы получаете его, но анализируете неправильно.

Причина

После вызова этого запроса GET (который вы используете):

https://api.github.com/search/users?q=some_name

Я получаю:

{
  "total_count": 0,
  "incomplete_results": false,
  "items": [

  ]
}

Где проблема

База по получению .json Я вижу, что элемент root - это JSON ОБЪЕКТ. В вашей ViewModel вы ожидаете List<User> (JSON ARRAY), что неверно. Вы получаете объект с 3 полями. И одно из этих полей - ваше List<User>.

Fix - description

Вам необходимо создать новый класс модели, описывающий данные, которые вы получаете. Чтобы разобрать (от json до Java) все полученные полученные данные, он должен содержать 3 поля.

Fix - код

Пример вашего нового класса:

public class GitHubResponse {
    private long totalCount;
    private boolean incompleteResults;
    private List<User> items;
}

и используйте этот класс везде во ViewModel и APIEndPoint.java. Для доступа к данным - средства получения объявлений для этого класса.

Общие подсказки / подсказки по проекту

  • Код переформатирования ( Ctrl + Alt + L )

  • Добавить состояние «старт» (так как после запуска вид приложения пуст)

  • Добавить пустое состояние (когда полученные данные пусты)

  • Добавить состояние загрузки (когда вы загружаете данные и ждете ответа)

  • Добавить состояние ошибки (при сбое подключения или некоторых проблемах с парсингом)

...