Метод Android Callback не заполняет список - PullRequest
0 голосов
/ 24 декабря 2018

Я сейчас работаю над проектом Android и пытаюсь разобрать URL-адрес.В моем "ApiClient" у меня нет проблем с разбором.Вот мой класс «ApiClient»:

public class ApiClient implements Callback<Map<String, Channel>> {

    static final String BASE_URL = "someURL";

    public void start() {

        Gson gson = new GsonBuilder()
                .setLenient()
                .create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        RestInterface restInterface = retrofit.create(RestInterface.class);

        Call<Map<String, Channel>> call = restInterface.getChannels();
        call.enqueue(this);

    }

    @Override
    public void onResponse(retrofit2.Call<Map<String, Channel>> call, Response<Map<String, Channel>> response) {
        System.out.println(response.code());
        if(response.isSuccessful()) {
            Map<String, Channel> body = response.body();
            List<Channel> channels = new ArrayList<>(body.values());
        }
...
    }

Я пытаюсь получить ответ в Список от использования обратного вызова в моем классе «Радио».Это место, где у меня проблемы.Я тоже пробовал эти три, но это не решило мою проблему:

private List<Channel> listChannels = new ArrayList<Channel>();
private List<Channel> listChannels = new ArrayList<>();
private List<Channel> listChannels = new List<>();

Вот мой класс "Радио":

public class Radio {
    private static final String STORAGE = "radio";
    private List<Channel> listChannels;

    public static Radio get() {
        return new Radio();
    }

    private SharedPreferences storage;

    private Radio() {
        storage = App.getInstance().getSharedPreferences(STORAGE, Context.MODE_PRIVATE);
    }

    public List<Channel> getData() {
        RestInterface restInterface = SingletonClass.getService();
        restInterface.getChannels().enqueue(new Callback<Map<String, Channel>>() {
            @Override
            public void onResponse(Call<Map<String, Channel>> call, Response<Map<String, Channel>> response) {
                if(response.isSuccessful()){
                    Map<String, Channel> body = response.body();
                    List<Channel> channels = new ArrayList<>(body.values());
                    loadChannels(channels);
                }
            }

            @Override
            public void onFailure(Call<Map<String, Channel>> call, Throwable t) {

            }
        });
        System.out.println(listChannels.get(1).getArtist());
        return listChannels;
    }

    public boolean isRated(int itemId) {
        return storage.getBoolean(String.valueOf(itemId), false);
    }

    public void setRated(int itemId, boolean isRated) {
        storage.edit().putBoolean(String.valueOf(itemId), isRated).apply();
    }

    private void loadChannels(List<Channel> channels){
        listChannels.clear();
        listChannels.addAll(channels);
    }


}

Вот мой класс интерфейса:

public interface RestInterface {

    @GET("someURL")
    retrofit2.Call<Map<String, Channel>> getChannels();
}

и мой SingletonClass:

public class SingletonClass{

    private static final Retrofit RETROFIT = new Retrofit.Builder()
            .baseUrl(someURL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    private static final RestInterface SERVICE = RETROFIT.create(RestInterface.class);


    public static RestInterface getService(){
        return SERVICE;
    }

}

Я не знаю, что мне делать, чтобы заполнить Список в моем классе Radio сейчас.Я полностью открыт для предложений.Спасибо за помощь.

1 Ответ

0 голосов
/ 24 декабря 2018

Получаете ли вы пустой список?Вы устанавливаете данные канала асинхронно в getData (), поэтому, если вы пытаетесь получить данные, прочитав их в следующей строке, они могут быть еще не загружены.

Это означает, что при вызове System.out.println(listChannels.get(1).getArtist()), вы не увидите результат loadChannels, потому что этот вызов происходит сразу после вызова enqueue(), когда loadChannels() работает в отдельном потоке.Если вы переместили это в onResponse (), вам может повезти больше.

В Android довольно простой способ сделать подобные вещи и взаимодействовать с пользовательским интерфейсом - использовать AsyncTask , который длявы бы выглядели примерно так:

private class loadChannelTask extends AsyncTask<Void, Void, List<Channel>> {
    protected List<Channel> doInBackground() {
        //get response
        //pass to load channels
    }

    protected void onPostExecute() {
         System.out.println(listChannels.get(1).getArtist()); //presumably the artist name
    }
}
...