Retrofit
(a type-safe HTTP client for Android and Java) HTTP网络请求工具
Retrofit使用步骤
1.定义一个接口(封装url地址和数据请求)
2.实例化Retrofit
3.调用Retrofit实例创建接口服务对象
4.接口服务对象调用接口中的方法获取Call对象
5.call对象执行请求(异步、同步请求)
封装url地址和数据请求的接口类
public interface INewsBiz {
/*
通过@GET注解标示为get请求 @GET中填写的value和baseUrl指定的地址组成完成的访问路径
baseUrl构造retrofit对象时指定
*/
@GET("api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
Call<ResponseBody> getResonsebody();
@GET("api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
Call<String> getJsonString();
@GET("category?app_id=161")
Call<List<Tea>> getTeas();
@GET("api/{type}?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41")
Call<NewsInfo> getNewsInfo(@Path("type") String type);//String type="GetFeeds"
//http://42.120.4.67/api/app/business/category?app_id=161
@GET("category")
Call<List<Tea>> getTeaByNetWork(@Query("app_id") int id);//int id=161
//api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41
@GET("api/GetFeeds")
Call<NewsInfo> getInfo(@QueryMap Map<String,String> map);
// @GET("api/{type}")
// Call<NewsInfo> getInfo(@Path("type") String type,@QueryMap Map<String,String> map);
//网络上下载文件
@GET("download")
Call<ResponseBody> downLoad();
//post请求中通过@FormUrlEncoded和@POST注解 指明访问的地址 @Field("向服务器提交的key")
@POST("LoginServlet")//采用post请求方式
@FormUrlEncoded //表单提交
Call<String> login(@Field("username") String username,
@Field("password") String password);
}
activity中具体使用
public class MainActivity extends AppCompatActivity {
private TextView tv;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv= (TextView) findViewById(R.id.tv);
iv= (ImageView) findViewById(R.id.iv);
// initRetrofit01();
// initRetrofit02();
// initRetrofit03();
// initRetrofit04();
// initRetrofit05();
// initRetrofit06();
// initRetrofit07();
initRetrofit08();
}
/**
* 采用同步访问的方式 excute()
*/
public void initRetrofit08(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)
.build();
final INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
new Thread(new Runnable() {
@Override
public void run() {
try {
Call<ResponseBody> call=iNewsBiz.getResonsebody();
// 采用同步方式请求数据
Response<ResponseBody> response=call.execute();
final String str=response.body().string();
tv.post(new Runnable() {
@Override
public void run() {
tv.setText(str);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 下载网络图片文件
*/
public void initRetrofit07(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.IMAGE_URL)
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<ResponseBody> call=iNewsBiz.downLoad();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccess()){
// String str=response.body().string();
// byte[] buff=response.body().bytes();
InputStream inputStream=response.body().byteStream();
Bitmap bm= BitmapFactory.decodeStream(inputStream);
iv.setImageBitmap(bm);
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
/**
* get 请求通过@queryMap注解动态传递多个参数
*/
public void initRetrofit06(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
//column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41
//将参数根据key-value对的形式存储到map集合中
Map<String,String> map=new HashMap<>();
map.put("column",0+"");
map.put("PageSize",20+"");
map.put("pageIndex",1+"");
map.put("val","100511D3BE5301280E0992C73A9DEC41");
Call<NewsInfo> call=iNewsBiz.getInfo(map);
//api/GetFeeds?column=0&PageSize=20&pageIndex=1&val=100511D3BE5301280E0992C73A9DEC41
// Call<NewsInfo> call=iNewsBiz.getInfo("GetFeeds",map);
call.enqueue(new Callback<NewsInfo>() {
@Override
public void onResponse(Call<NewsInfo> call, Response<NewsInfo> response) {
if(response.isSuccess()){
List<NewsInfo.ParamzBean.FeedsBean> news=
response.body().getParamz().getFeeds();
StringBuilder sb=new StringBuilder();
for(NewsInfo.ParamzBean.FeedsBean feed:news){
sb.append(feed.getData().getSubject());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<NewsInfo> call, Throwable t) {
}
});
}
/**
get请求 通过@query注解动态传递参数的值
*/
public void initRetrofit05(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.TEABASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<List<Tea>> call=iNewsBiz.getTeaByNetWork(161);
call.enqueue(new Callback<List<Tea>>() {
@Override
public void onResponse(Call<List<Tea>> call, Response<List<Tea>> response) {
if(response.isSuccess()){
StringBuilder sb=new StringBuilder();
List<Tea> list=response.body();
for(Tea t:list){
sb.append(t.getProduct_cat_name());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<List<Tea>> call, Throwable t) {
}
});
}
/**
* get请求 通过占位符指定path路径
*/
public void initRetrofit04(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<NewsInfo> call=iNewsBiz.getNewsInfo("GetFeeds");
call.enqueue(new Callback<NewsInfo>() {
@Override
public void onResponse(Call<NewsInfo> call, Response<NewsInfo> response) {
if(response.isSuccess()){
List<NewsInfo.ParamzBean.FeedsBean> news=
response.body().getParamz().getFeeds();
StringBuilder sb=new StringBuilder();
for(NewsInfo.ParamzBean.FeedsBean feed:news){
sb.append(feed.getData().getSubject());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<NewsInfo> call, Throwable t) {
}
});
}
/**
* 普通的get请求 返回的数据为gson解析后的list集合
*/
public void initRetrofit03(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.TEABASE_URL)
//如果服务器返回的时json格式数据 设置了GsonConverterFactory
//实现对对象的转化
// 自定义数据解析器 只要解析器继承Converter.Factory即可
.addConverterFactory(GsonConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<List<Tea>> call=iNewsBiz.getTeas();
call.enqueue(new Callback<List<Tea>>() {
@Override
public void onResponse(Call<List<Tea>> call, Response<List<Tea>> response) {
if(response.isSuccess()){
List<Tea> list=response.body();//获取解析后的集合
StringBuilder sb=new StringBuilder();
for(Tea t:list){
sb.append(t.getProduct_cat_name());
}
tv.setText(sb.toString());
}
}
@Override
public void onFailure(Call<List<Tea>> call, Throwable t) {
}
});
}
/**
* 普通get请求 返回的数据为String类型
*/
public void initRetrofit02(){
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)
//设置回调时的适配器 get请求后可以返回String字符串类型的内容
.addConverterFactory(ScalarsConverterFactory.create())
.build();
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
Call<String> call=iNewsBiz.getJsonString();
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccess()){
tv.setText(response.body());
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
}
/**
* 普通get请求
*/
public void initRetrofit01(){
//构建Retrofit网络访问对象
Retrofit retrofit=new Retrofit
.Builder()
.baseUrl(Constant.BASE_URL)//设置访问的跟路径
.build();
//根据接口的字节码文件对象获取接口的对象
INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
//调用接口中定义的函数
Call<ResponseBody> call=iNewsBiz.getResonsebody();
/*enqueue 采用异步访问数据 execute()采用同步访问数据*/
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccess()){//成功的获取响应
try {
String result=response.body().string();//获取网络访问的字符串
tv.setText(result);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
}
retrofit底层源码
底层使用注解反射 动态代理 okhttp访问网络
Retrofit 底层使用注解反射 动态代理
- Retrofit retrofit=new Retrofit.Builder().baseUrl(url).build();
源码:
public static final class Builder {
private List<Converter.Factory> converterFactories = new ArrayList<>();
private okhttp3.Call.Factory callFactory;
.....
public Builder() {
...
converterFactories.add(new BuiltInConverters());
}
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null"); //检查传递的baseUrl不能为null
//将根路径封装成HttpUrl对象
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
....
public Builder baseUrl(final HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
//检查根路径是否以/结尾
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
return baseUrl(new BaseUrl() {
@Override public HttpUrl url() {
return baseUrl;
}
});
}
.....
public Builder baseUrl(BaseUrl baseUrl) {
this.baseUrl = checkNotNull(baseUrl, "baseUrl == null");
return this;
}
.....
public Retrofit build() {
//判断根路径必须存在
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//retrofit底层采用okhttp访问网络
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//CallAdapter.Factory 主要用于对call进行转化
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(Platform.get().defaultCallAdapterFactory(callbackExecutor));
//Converter.Factory 主要用于转化数据
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
//构建retrofit对象
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
2.INewsBiz iNewsBiz=retrofit.create(INewsBiz.class);
public <T> T create(final Class<T> 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, 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);
}
return loadMethodHandler(method).invoke(args);
}
});
}
CallBack
retrofit请求数据返回的接口 onResponse() onFailure()
Call
接口主要用用就是发送Http请求 默认实现的okHttpCall