我有以下情况:我的程序从服务器下载数据,然后将其添加到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
那么,如何解决此问题,因为我需要先获取数据然后返回数组?
答案 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
}
}