学习Retrofit 使用和理解

基本用法

  1. 添加依赖

    1
    2
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'

    在build.gradle添加retrofit2的最新版本就行了

  2. 构建retrofit

    构建retrofit实例,使用retrofit来处理HTTP请求

    1
    2
    3
    4
    Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
  3. 构建请求接口

    定义Http请求接口:请求链接,参数,返回接口等(要提前定义好数据类bean,即json格式解析的数)

    1
    2
    3
    4
    public interface GithubService {
    @GET("users/{user}/repos")
    Call<List<GithubRepo>> listRepos(@Path("user") String user);
    }

    使用retrofit创建http请求服务

    1
    GithubService githubService = retrofit.create(GithubService.class);
  4. 执行请求(使用默认CallAdapter,)

    执行http请求

    异步

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Call<List<GithubRepo>> call = githubService.listRepos("zsyzzx");
    call.enqueue(new Callback<List<GithubRepo>>() {
    @Override
    public void onResponse(Call<List<GithubRepo>> call, Response<List<GithubRepo>> response) {
    //请求成功,respond.body()是数据,在此加上自己需要的操作
    List<GithubRepo> repos = response.body();
    Log.e("success",repos.toString());
    listview.setAdapter(new GithubRepoAdapter(MainActivity.this,repos));
    }
    @Override
    public void onFailure(Call<List<GithubRepo>> call, Throwable t) {
    //网络请求失败,失败处理
    Toast.makeText(MainActivity.this, "Error: "+t.toString() , Toast.LENGTH_SHORT).show();
    }
    });

    同步

    在Android主线程运行时,要新开一个线程,否则会报错

    1
    2
    Call<List<GithubRepo>> call = githubService.listRepos("zsyzzx");
    Response<List<GithubRepo>> lists = call.execute();
  5. 处理返回体

    不论是同步请求,还是异步请求,其原生的返回数据体是Response<T> 如果要操作网络请求返回结果的话, 就是操作Response<T>,可以使用debug功能看Response里的参数,每个参数的意义,可以使用chrome的控制台来了解

    1_retrofit

基础构建

Retrofit 构建

retrofit 使用Retrofit.builder来构建retrofit实例

1
2
3
4
5
6
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(ProtoConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();

下面构建Retrofit实例时常用的一些基本参数

baseUrl()

这是基本的访问链接一定要以’/‘结束,下面是链接规则

baseUrl 注解中的参数 结果 备注
https://api.github.com/path/xxx/ /users https://api.github.com/users 绝对路径,从主机地址开始
https://api.github.com/path/xxx/ users https://api.github.com/path/xxx 相对路径,直接在baseUrl下添加路径
https://api.github.com/path/xxx/ https://blog.seventeams.cn https://blog.seventeams.cn 这需要注解@Url才能变更整个链接

上面的机制使链接配置方便,灵活,可以设置外链

addConverterFactory()

设置数据转换,即将服务器的数据格式(XML,JSON,ProtBuf等)转换成自己需要的,容易处理的数据类,也支持自定义Converter, 支持的转换器如下

2_retrofit

注意事项

  • 可以设置多个Converter
  • Converter设置要注意顺序,一旦数据遇到能处理其的转换器,就不继续往下传,而Json的转换器默认处理所有的数据

addCallAdapterFactory()3_retrofit

优化技巧

  • 一个应用只创建,使用一个Retrofit实例,
  • 对于多链接请求,使用Rxjava处理

基本注解

  • Retrofit的注解就是Http方法,参数等的封装,

    Retrofit 利用这些注解获取相应的参数构造一个个Http请求,利用Okhttp向服务器发起请求,然后接受服务器的反应,并自动的做些转化处理等

    大概流程是: retrofit => okhttp => 服务器

  • 要理解其具体的意义,最好学习Http相关知识,或者使用Chrome的Debug工具看一个网页的Http各个参数的意义

  • 以下的部分代码,教程源自以下链接

1
2
//retrofit的一些注解,可以转换成这个注解
@HTTP(method = "method", path = "xxx", hasBody = false)

@Get("xxx/{path}/xx")

  • Http中Get请求,从服务器获取数据
  • ()中参数可省去,代表使用baseUrl请求服务器
  • {}中的参数代表可变路径,可以在接口定义中,作为一个参数得到用户输入,得到一个动态地址,与@path一起搭配使用

@Path()

用来获取到{}的实际值(用户输入的值),()中参数为{}中的值

1
2
@GET("users/{user}/repos")
Call<List<GithubRepo>> listRepos(@Path("user") String user);

@Query()@QueryMap()

查询参数, 与GET方法一起用, @Query(queryParameter)转换成URL 就是 baseUrl/Get里面的参数?queryParameter=xxx(用户输入的值)

1
2
3
4
5
6
7
8
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
//对应的链接:baseUrl/group/[groupId]?sort=[sort]
// []代表取参数的值
// @QueryMap()
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);

@Post()

  • 向服务传送数据
  • 一般与@Body,@FormUrlEncoded,@Multipart使用

@Body

传送自定义数据格式,可以传送Json数据等

@Headers()@Header

  • 定义请求头部,一部用作和服务器约定传送的数据格式以及身份验证和一些其他的请求参数

    1
    2
    3
    4
    5
    6
    @Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
    })
    @GET("users/{username}")
    Call<User> getUser(@Path("username") String username);
  • Headers 只能设置固定的值

that headers do not overwrite each other. All headers with the same name will be included in the request

  • Header 能动态设置Header参数

    Headers that need to be added to every request can be specified using an OkHttp interceptor.(拦截器)

还不会用(没用到、没用过)

@FormUrlEncoded

  • 一般与@Field@FieldMap一起用
  • 表单上传请求??

@Multipart

  • 一般与@PartPartMap一起用
  • 一般用作文件上传

执行请求(默认的CallAdapter call)

异步调用call.enqueue(Callback) => 比较符合Http请求格式(一个Request 对应一个 Response)

分为两个操作函数 =>{参考Javascript的callback机制}

onResponse() 成功时的操作函数,得到服务器返回的数据:body(), header()等

onFailure() 失败时的处理,可以自定义请求错误操作

如果要一次请求多个链接:使用Rxjava来处理多个链接的处理

1
2
3
4
5
6
7
8
9
Call<List<GithubRepo>> call = githubService.listRepos("zsyzzx");
call.enqueue(new Callback<List<GithubRepo>>() {
@Override
public void onResponse(Call<List<GithubRepo>> call, Response<List<GithubRepo>> response) {
List<GithubRepo> repos = response.body();
}
@Override
public void onFailure(Call<List<GithubRepo>> call, Throwable t) {
});

同步调用

返回http后的结果,在Android中必须在后台、新线程进行

1
2
Call<List<GithubRepo>> call = githubService.listRepos("zsyzzx");
Response<List<GithubRepo>> lists = call.execute();

使用Rxjava

占坑中

Okhttp拦截器

占坑中

授权机制

占坑中

log使用

占坑中

参考链接

http://blog.csdn.net/carson_ho/article/details/73732076

http://www.jianshu.com/p/308f3c54abdd

http://square.github.io/retrofit/

https://futurestud.io/tutorials/retrofit-getting-started-and-android-client

源码解读

Retrofit2 源码解析