【问题标题】:Android Callback method not fills the listAndroid 回调方法未填充列表
【发布时间】:2018-12-24 18:06:59
【问题描述】:

我现在正在开发一个 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 课程中填写列表。我完全愿意接受建议。感谢您的帮助。

【问题讨论】:

  • 能否在onFailure回调方法中记录错误,看看会发生什么
  • 成功了。我得到空指针,索引类型错误的数组,但这与初始化无关。我认为我无法将数据填充到使用“loadChannels(channels)”的“listChannels”中。

标签: java android callback retrofit2


【解决方案1】:

你得到一个空列表吗?您在 getData() 中异步设置通道数据,因此如果您尝试通过在下一行中读取数据来获取数据,它可能尚未加载。

这意味着当您调用 System.out.println(listChannels.get(1).getArtist()), 时,您不会看到 loadChannels 的结果,因为该调用发生在您调用 enqueue() 之后,而 loadChannels() 在单独的线程上运行。如果你把它移到 onResponse() 中,你可能会有更多的运气。

在 Android 中,执行此类操作并与 UI 交互的一种相当简单的方法是使用 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
    }
}

【讨论】:

  • 你能给我一个“获取响应”部分的例子吗?因为我检查了链接,但仍然不明白如何获得响应。
  • 我对回调接口或改造2不是很熟悉,但你也可以尝试将getData()方法重新设计成public void getData(Callback&lt;Something&gt;)like so:之类的方法。在任何情况下,您与listChannels 交互的逻辑都需要在 onResponse()(用于改造)或 doInBackground() 用于 AsyncTask。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多