在 Retrofit 中使用 Call Enqueue 函数
Using Call Enqueue function in Retrofit
我正在为我的应用程序使用 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();
}
});
}
不知道入队函数要实现什么。关于如何使用回调的改造网站上给出的很少。假设所有其他代码都工作正常。这里 MovieResponse
对象是由 movieDB API return 编辑的,它包含一个 Movie
数组和一些额外信息。我以这样的方式实现它,以便一旦我从那里得到 MovieResponse
中的响应,我就可以使用 getMovies()
提取,这将 return 电影列表。
当我 运行 我只是得到 null object reference
因为 response
是空的。我试图搜索有关使用 new Retrofit-2.0.0
的教程,尤其是有关使用 enqueue 函数的教程,但我运气不好。再加上一个问题 updateMovies()
应该在哪里调用。可以直接在mainactivity中调用吗?是否自动改造 运行 后台线程上的网络调用?
对于 Retrofit 2,即使出现故障也会调用 onResponse
。您已使用!response.isSuccess()
检查是否响应不成功。但是你只是记录了它 - 如果它是真的(即不成功)。相反,您可以记录 response.errorBody().string()
以查看 api 服务器是否指定了错误,并且您应该调用类似 return
的内容来退出 onResponse
回调,因为 response.body()
不能' 被强制转换为 MovieResponse
,因此出现空异常。
顺便说一句,你的代码是正确的,但如果你只是从Retrofit开始,使用1.9版本会更简单,因为2.0仍然是测试版(虽然很稳定,但缺乏教程)。
@AbKDs,我不知道你是否已经解决了它,但在与改造 2 进行了一些斗争之后我发现你需要将“http://api.themoviedb.org”作为你的 baseUrl 并将整个路径添加到@得到。像这样:@GET("/3/discover/movie")
然后将查询添加为接口调用的参数。
使用来自 OkHttp 的拦截器在 Retrofit 1.9 上,您可以使用 RequestInterceptor 拦截请求,但它已在 Retrofit 2.0 上被删除,因为 HTTP 连接层已移至 OkHttp。
因此,我们必须从现在开始从 OkHttp 切换到拦截器。
首先,你必须将它添加到 build.gradle
compile 'com.squareup.okhttp:okhttp:2.5.0'
然后创建一个带有拦截器的 OkHttpClient 对象,如下所示:
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 解析概念。 Base URL 和 @Url 不仅简单地组合在一起,而且已经以与替代方法相同的方式解决。请查看下面的示例以进行说明。
我正在为我的应用程序使用 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();
}
});
}
不知道入队函数要实现什么。关于如何使用回调的改造网站上给出的很少。假设所有其他代码都工作正常。这里 MovieResponse
对象是由 movieDB API return 编辑的,它包含一个 Movie
数组和一些额外信息。我以这样的方式实现它,以便一旦我从那里得到 MovieResponse
中的响应,我就可以使用 getMovies()
提取,这将 return 电影列表。
当我 运行 我只是得到 null object reference
因为 response
是空的。我试图搜索有关使用 new Retrofit-2.0.0
的教程,尤其是有关使用 enqueue 函数的教程,但我运气不好。再加上一个问题 updateMovies()
应该在哪里调用。可以直接在mainactivity中调用吗?是否自动改造 运行 后台线程上的网络调用?
对于 Retrofit 2,即使出现故障也会调用 onResponse
。您已使用!response.isSuccess()
检查是否响应不成功。但是你只是记录了它 - 如果它是真的(即不成功)。相反,您可以记录 response.errorBody().string()
以查看 api 服务器是否指定了错误,并且您应该调用类似 return
的内容来退出 onResponse
回调,因为 response.body()
不能' 被强制转换为 MovieResponse
,因此出现空异常。
顺便说一句,你的代码是正确的,但如果你只是从Retrofit开始,使用1.9版本会更简单,因为2.0仍然是测试版(虽然很稳定,但缺乏教程)。
@AbKDs,我不知道你是否已经解决了它,但在与改造 2 进行了一些斗争之后我发现你需要将“http://api.themoviedb.org”作为你的 baseUrl 并将整个路径添加到@得到。像这样:@GET("/3/discover/movie") 然后将查询添加为接口调用的参数。
使用来自 OkHttp 的拦截器在 Retrofit 1.9 上,您可以使用 RequestInterceptor 拦截请求,但它已在 Retrofit 2.0 上被删除,因为 HTTP 连接层已移至 OkHttp。
因此,我们必须从现在开始从 OkHttp 切换到拦截器。 首先,你必须将它添加到 build.gradle
compile 'com.squareup.okhttp:okhttp:2.5.0'
然后创建一个带有拦截器的 OkHttpClient 对象,如下所示:
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 解析概念。 Base URL 和 @Url 不仅简单地组合在一起,而且已经以与替代方法相同的方式解决。请查看下面的示例以进行说明。