开新坑辣!一直以为本身框架了解的特别少,大多只知其名而不知实现原理,然而几乎每次面试都会被问及框架。因此颇有必要总结一些经常使用的框架,但愿本身能坚持把这个『框架学习』系列的新坑填的厚实一点!android
1.概述git
a.Retrofit是Square公司推出的一个基于RESTful风格的HTTP网络框架。github
相关连接地址:面试
b.与OkHttp的关系:设计模式
是对OkHttp网络请求框架的二次封装,本质还是OkHttp。即网络请求的工做本质上是由OkHttp完成,而Retrofit仅负责网络请求接口的封装。流程如图:bash
- App应用程序经过Retrofit请求网络,其实是使用Retrofit接口层封装请求参数、Header、Url等信息,以后由OkHttp完成后续的请求操做。
- 在服务端返回数据以后,OkHttp将原始的结果交给Retrofit,Retrofit会根据用户的需求对结果进行解析。
- 经过使用大量的设计模式进行功能模块的解耦,使得上面的过程进行得更加简单和流畅。
c.其余网络框架简介:服务器
相比于上述两种网络框架,Retrofit具备的优势:网络
- 遵循Restful API设计风格,简洁易用
- 支持同步&异步网络请求
- 支持多种数据的解析&序列化格式(Gson、 Json、XML、 Protobuf)
- 支持对RxJava支持
- 注解化配置高度解耦、采用大量设计模式简化使用
2.使用方式app
大体分红八个步骤:框架
step1:添加Retrofit库、OkHttp库、数据解析器集成库的依赖,并注册网络权限
在app文件包下的build.gradle中添加依赖,这里用的是JSON数据解析器:
compile 'com.squareup.retrofit2:retrofit:2.4.0'
compile 'com.squareup.okhttp3:okhttp:3.10.0'
compile 'com.squareup.retrofit2:converter-gson:2.4.0'
复制代码
在AndroidManifest.xml中注册权限:
<uses-permission android:name="android.permission.INTERNET"/>
复制代码
step2:建立接收服务器返回数据的类
请求后服务器会返回数据,须要根据返回数据的格式和解析方式(Json、XML等)来定义实体类Model。
假设有返回数据格式为以下JSON,其中,若是用户名和密码匹配成功,则code值为1,反之为0:
{
"code":1,
"data":{
"id":10001,
"username":"Tom",
"email":"888888888@qq.com",
"tel":"18088888888"
},
"message":"success"
}
复制代码
则对应的实体类UserInfoModel:
public class UserInfoModel {
public int code;
public UserInfo data;
public String message;
public static class UserInfo{
public int id;
public String username;
public String email;
public String tel;
}
}
复制代码
step3:建立用于描述网络请求的接口
定义一个网络请求的接口,接口函数里要定义URL路径、请求参数、返回类型。其中,须要使用注解来描述请求类型和请求参数。
public interface Interface {
@GET("URL")
Call<Model> getCall(@Query("xxx") String xxx);
// 用@GET("URL")声明了URL路径
// 用getCall()接收网络请求数据,并用注解@Query("xxx") 声明了请求参数
// 该方法会返回一个Retrofit的Call对象,这里声明了这个对象处理的数据类型为自定义Model
}
复制代码
在上例中,对应的UserMgrService接口以下,当发送请求参数为Tom和123456时,请求将发送给的URL为『login?username=Tom&pwd=123456』,并会返回以前定义的GSON数据:
public interface UserMgrService{
@GET("login")
Call<UserInfoModel> login(@Query("username") String username,@Query("pwd") String pwd);
}
复制代码
经常使用的注解含义如图:
这里能够发现,@GET和@Query搭配使用,@POST和@Field搭配使用。
step4:建立Retrofit对象并设置数据解析器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("URL") //设置网络请求的Url地址,注意以要以斜线(表明根目录)结尾
.addConverterFactory(GsonConverterFactory.create()) //设置数据解析器,这里表示用的是JSON解析返回值
.build();
复制代码
经常使用的数据解析器如图:
step5:生成接口对象
因为是interface不是class,没法直接调用内部方法,须要利用已建立的Retrofit对象去生成代理的接口对象。
UserMgrService service=retrofit.create(UserMgrService.class);
复制代码
step6:调用接口方法返回Call对象
调用接口对象的方法,返回一个能够执行网络访问的网络工做对象。
Call<UserInfoModel> call=service.login("Tom","123456");
复制代码
step7:发送网络请求(异步 / 同步)
a.同步:调用Call对象execute()
,返回结果是响应体。
//开线程进行网络请求
new Thread(new Runable()){
@Override
pubblic void run(){
Response<UserInfoModel> response=null;
try{
response=call.execute();
}catch{
e.printStackTrace();
}
//处理服务器返回的数据
}
}.start();
复制代码
b.异步:调用Call对象enqueue()
,参数是一个回调。
//异步时,框架中已经封装好数据转换、线程切换的操做,无需手动开线程
call.enqueue(new CallBack<UserInfoModel>(){
@Override
public void onResponse(Call<UserInfoModel> call,Response<UserInfoModel> response){
//处理服务器返回的数据
}
@Override
public void onFailure(Call<UserInfoModel> call,Throwable t){
}
});
复制代码
step8: 处理服务器返回的数据
如今能够去打印出返回结果:
Log.i("response","code:"+response.body().code);//结果为"code:1"
复制代码
下面给出官方给的simple demo,便于更好的理解Retrofit的使用步骤:
//step3:
public interface GitHub {
@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(
@Path("owner") String owner,
@Path("repo") String repo);
}
public static void main(String... args) throws IOException {
// step4:Create a very simple REST adapter which points the GitHub API.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
// step5:Create an instance of our GitHub API interface.
GitHub github = retrofit.create(GitHub.class);
// step6:Create a call instance for looking up Retrofit contributors.
Call<List<Contributor>> call = github.contributors("square", "retrofit");
// step7:Fetch and print a list of the contributors to the library.
List<Contributor> contributors = call.execute().body();
//step8:
for (Contributor contributor : contributors) {
System.out.println(contributor.login + " (" + contributor.contributions + ")");
}
}
复制代码
实例:这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
以上,能够看到,Retrofit可根据不一样的接口定义,灵活地生成对应的网络工做对象,而后利用这个对象去访问网络。它就像一个工厂,只提供产品,自己不处理网络请求,而是让产品去处理网络请求。
下一篇将进行Retrofit的源码分析~