数据已从服务器加载,但未添加到arraylist

时间:2019-04-01 19:07:19

标签: android retrofit2

我有以下情况:我的程序从服务器下载数据,然后将其添加到ArrayList

static List<Film> generateFilms(){
        Log.i(Tag, "In generate films");
        List <Film> films = new ArrayList<>();
        String BaseUrl = "http://www.omdbapi.com/";
        Retrofit.Builder builder = new Retrofit.Builder().baseUrl(BaseUrl)
                .addConverterFactory(GsonConverterFactory.create());
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS);
        httpClient.addInterceptor(chain -> {
            Request original =  chain.request();
            Request.Builder requestBuilder = original.newBuilder()
                    .header("Authorization", "auth-value");
            Request request = requestBuilder.build();
            return chain.proceed(request);
        });
        Retrofit retrofit = builder.build();
        APIService apiService  = retrofit.create(APIService.class);
        final Call<Film> filmsCall = apiService.getFilms();
        filmsCall.enqueue(new Callback<Film>() {
            @Override
            public void onResponse(@NonNull Call<Film> call, @NonNull Response<Film> response) {
                if (response.isSuccessful()){
                    Film film = response.body();
                    films.add(film);
                    Log.i(Tag, "Response: "+Objects.requireNonNull(response.body()).getTitle());
                }
                else {
                    Log.i(Tag, "Response code: "+response.code());
                }
            }

            @Override
            public void onFailure(@NonNull Call<Film> call, @NonNull Throwable t) {
                Log.i(getClass().getSimpleName(), "Error: "+t);
            }
        });

        Log.i(Tag, "Size = "+films.size());
        return films;
    }

但是这样做的方式很奇怪:它首先返回一个数组,然后获取数据(正如我从日志中看到的那样)。这是日志:

2019-04-01 22:00:06.766 4974-4974/asus.example.com.exercise5 I/DataUtil: In generate films
2019-04-01 22:00:06.889 4974-4974/asus.example.com.exercise5 I/DataUtil: Size = 0
2019-04-01 22:00:07.367 4974-4974/asus.example.com.exercise5 I/DataUtil: Response: Batman

那么,如何解决此问题,因为我需要先获取数据然后返回数组?

1 个答案:

答案 0 :(得分:0)

Call<T>.enqueu()以异步方式运行,因此您不能从generateFilms方法本身返回数据,而只能在onResponse中执行所有必需的操作或创建自定义回调。

示例:

interface OnLoaded {
  void onLoaded(Film film);
}

void generateFilms(OnLoaded callback) {
  ...
 filmsCall.enqueue(new Callback<Film>() {
            @Override
            public void onResponse(@NonNull Call<Film> call, @NonNull Response<Film> response) {
                if (response.isSuccessful()){
                    Film film = response.body();
                    mFilms.add(film);
                    Log.i(Tag, "Response: "+Objects.requireNonNull(response.body()).getTitle());

                    callback.onLoaded(film);
                }
                else {
                    Log.i(Tag, "Response code: "+response.code());
                }
            }

并使用它:

private List<Film> mFilms = new ArrayList<Film>();  // class-level field

generateFilms(new OnLoaded() {
  @Override
  public void onLoaded(Film film) {
    mFilms.add(film);
    // do actions with film or mFilms if you need
  }
}