Использование функции "Завершение вызова" в "Дооснащении"
Я использую Retrofit-2.0.0
для своего приложения. Теперь каждый учебник по Retrofit, который я нашел в Интернете, основан на более раннем Retrofit
и там не было интерфейса Call<T>
. Это первый раз, когда я использую Retrofit, и я неоднократно получаю null object reference
. Вот мой интерфейс сетевой модели
public interface TMovieDBService {
@GET("/movie")
Call<MovieResponse> getMovieResponse(@Query("sort_by") String sortKey,
@Query("api_key") String apiKey);
}
И это моя функция updateMovies()
, которая обновляет список фильмов.
void updateMovies() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.themoviedb.org/3/discover")
.addConverterFactory(GsonConverterFactory.create())
.build();
String sortKey = "popularity.desc";
TMovieDBService service = retrofit.create(TMovieDBService.class);
Call<MovieResponse> call = service.getMovieResponse(sortKey, ApiKey.API_KEY);
call.enqueue(new Callback<MovieResponse>() {
@Override
public void onResponse(Response<MovieResponse> response) {
Log.d(LOG_TAG, "Reached this place");
if (!response.isSuccess()) {
Log.d(LOG_TAG, "No Success");
}
mMovieList = response.body().getMovies(); // <- response is null here
// Log.d(LOG_TAG, "Couldn't not reach this place");
mMovieAdapter.notifyDataSetChanged();
Log.d(LOG_TAG, "Response returned by website is : " + response.code());
}
@Override
public void onFailure(Throwable t) {
// Toast for the moment
// Appropriate error handling code should be present here
Toast.makeText(getActivity(), "Failed !", Toast.LENGTH_LONG).show();
}
});
}
Я не знаю, что реализовать в функции enqueue. На обновленном веб-сайте очень мало информации о том, как использовать обратный вызов. Предположим, что все остальные коды работают нормально. Здесь объект MovieResponse
возвращается API-интерфейсом movieDB, который содержит массив Movie
и некоторую дополнительную информацию. Я реализую его таким образом, чтобы после получения ответа от MovieResponse
оттуда я смог извлечь с помощью getMovies()
, который вернет список фильмов.
Когда я запускаю, я просто получаю null object reference
, потому что response
имеет значение null. Я попытался найти учебники по использованию нового Retrofit-2.0.0
, особенно при использовании функции enqueue, но мне не повезло. Плюс еще один вопрос, куда следует вызывать updateMovies()
. Могу ли я вызвать его непосредственно в mainactivity. Модернизируется ли автоматический запуск сетевого вызова в фоновом потоке?
Ответы
Ответ 1
С Retrofit 2, onResponse
вызывается, даже если есть сбой. Вы проверили, не отвечает ли ответ с помощью !response.isSuccess()
. Но вы только что зарегистрировали его - если это правда (т.е. Не удалось). Вместо этого вы можете записать response.errorBody().string()
, чтобы узнать, указывает ли api сервер ошибку, и вы должны вызвать что-то вроде return
для выхода из обратного вызова onResponse
, поскольку response.body()
не может быть отправлено на MovieResponse
, следовательно, значение null исключение.
Кстати, ваш код правильный, но если вы только начинаете с Retrofit, было бы проще использовать версию 1.9, так как 2.0 все еще является бета-версией (очень стабильной, хотя и отсутствием учебников).
Ответ 2
Используйте Interceptor из OkHttp On Retrofit 1.9, вы можете использовать RequestInterceptor для перехвата запроса, но он уже удален в Retrofit 2.0, так как уровень подключения HTTP был перемещен в OkHttp.
В результате мы теперь должны переключиться на Interceptor из OkHttp.
Сначала вы должны добавить его в build.gradle
compile 'com.squareup.okhttp:okhttp:2.5.0'
а затем создайте объект OkHttpClient с Interceptor следующим образом:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
// Do anything with response here
return response;
}
});
И затем передайте созданный клиент в цепочку Retrofit Builder.
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://api.themoviedb.org/3/discover/").addConverterFactory(GsonConverterFactory.create()).client(client).build();
Удалите '/' из вашего @GET ( "/abc" )
потому что Retrofit 2.0 поставляется с новой концепцией разрешения URL. Базовый URL-адрес и @Url не просто объединены вместе, но были решены так же, как и то, что делает. Пожалуйста, ознакомьтесь с приведенными ниже примерами для уточнения.
![></a> <a href=]()
![></a> <a href=]()
![]()
Чтобы узнать больше о Retrofit 2.0
Ответ 3
@AbKDs, я не знаю, если вы уже решили это, но я узнал после некоторой борьбы с retrofit 2, что вам нужно поставить " http://api.themoviedb.org" как ваш baseUrl и добавьте весь путь в @GET. Например: @GET ( "/3/обнаружение/фильм" )
И затем вы добавляете свои запросы в качестве параметров для вашего вызова Call.