内容导图
1、依赖库导入
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
2、基本使用
2.1、定义请求接口
import hq.demo.net.model.WeatherBeans;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
public interface NetService {
@GET("?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json")
Call<WeatherBeans> requestWeatherBeans();
@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(
@Field("app") String app,
@Field("weaid") String weaid,
@Field("appkey") String appkey,
@Field("sign") String sign,
@Field("format") String format);
}
这里要注意的是@FormUrlEncoded,如果post请求不加上它就会报错如下:java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)for method NetService.requestWeatherBeans
为什么要加上这个注释,后面分析。
2.2、get请求网络数据
private void doGet() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<WeatherBeans> call = netService.requestWeatherBeans();
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
Log.d("######beans", beans.toString());
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("cityName", bean.getCitynm());
Log.d("days", bean.getDays());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
结果:
09-07 22:05:32.537 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.537 8546-8546/hq.demo.net D/days: 2018-09-05
09-07 22:05:32.537 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.537 8546-8546/hq.demo.net D/days: 2018-09-06
09-07 22:05:32.537 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.537 8546-8546/hq.demo.net D/days: 2018-09-07
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-08
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-09
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-10
09-07 22:05:32.538 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:05:32.538 8546-8546/hq.demo.net D/days: 2018-09-11
2.3、post请求
private void doPost() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
Call<WeatherBeans> call = netService.requestWeatherBeans("weather.future","1","10003","b59bc3ef6191eb9f747dd4e83c99f2a4","json");
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("cityName", bean.getCitynm());
Log.d("days", bean.getDays());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
}
结果:
09-07 22:11:37.351 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-05
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-06
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-07
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-08
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-09
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-10
09-07 22:11:37.352 8546-8546/hq.demo.net D/cityName: 北京
09-07 22:11:37.352 8546-8546/hq.demo.net D/days: 2018-09-11
因为:http://api.k780.com/?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json是可以同时接受get/post请求的
2.4、步骤解析
使用retrofit从网络请求回来的数据采用gson数据解析,在通过建造者模式创建出Retrofit的时候回通过addConverterFactory添加一个GsonConverterFactory,GsonConverterFactory通过create()创建其实例,默认情况下会使用Gson,create()的重载方法create(Gson gson),也是可以传入一个Gson实例的,
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.k780.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
NetService netService = retrofit.create(NetService.class);
然后Retrofit通过动态加载的将自定义的接口接管
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
2.5、通过Call的实现类OKHttpCall与OKHttp进行网络请求
其实retrofit就是通过okhttp来进行网络请求的
Call<WeatherBeans> call = netService.requestWeatherBeans();
call.enqueue(new Callback<WeatherBeans>() {
@Override
public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
if (response.isSuccessful()) {
WeatherBeans beans = response.body();
for (WeatherBeans.ResultBean bean : beans.getResult()) {
Log.d("cityName", bean.getCitynm());
Log.d("days", bean.getDays());
}
}
}
@Override
public void onFailure(Call<WeatherBeans> call, Throwable t) {
}
});
3、注解说明
见注解详解