文章来自于
准备工作
| 1 | //retrofit2.0 | 
定义接口
在官方文档中,第一句话就是”Retrofit turns your HTTP API into a Java Interface”
我们的项目调用的接口来自于Gank的接口,例如:http://gank.io/api/data/Android/10/1
返回的Json数据:

定义一个接口类
| 1 | public interface GankApi { | 
分析接口的定义
http://gank.io/api/data/Android/10/1
在这里我们将接口分为两部分baseUrl和接口定义,在上面的接口定义中,使用GET请求,直接请求了api/data/Android/10/1,这样我们就能和后面定义的baseUrl拼接成完整的接口了。
基本请求
官方文档中 The Retrofit class generates an implementation of the GithubService interface.
意思就是直接把Retrofit的接口变成一个类
- 创建一个Retrofit - 1 
 2
 3
 4- Retrofit retrofit = new Retrofit.Builder() 
 .baseUrl("http://gank.io")
 .addConverterFactory(GsonConverterFactory.create())
 .build();
- 通过retrofit的create方法创建接口对象 - 1 - GankApi api = retrofit.create(GankApi.class); 
- 直接调用接口方法,返回一个Call - 1 - Call<GankBean> call = api.getAndroidInfo(); 
- 异步请求 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21- call.enqueue(new Callback<GankBean>() { 
 @Override
 public void onResponse(Call<GankBean> call, Response<GankBean> response) {
 GankBean.ResultsBean bean = response.body().getResults().get(0);
 mTextView.setText(
 "_id:"+bean.get_id()+"\n"
 + "createdAt:" + bean.getCreatedAt() + "\n"
 + "desc:" + bean.getDesc() + "\n"
 + "images:" + bean.getImages() + "\n"
 + "publishedAt:" + bean.getPublishedAt() + "\n"
 + "source" + bean.getSource() + "\n"
 + "type:" + bean.getType() + "\n"
 + "url: " + bean.getUrl() + "\n"
 + "who:" + bean.getWho());
 }
 @Override
 public void onFailure(Call<GankBean> call, Throwable t) {
 }
 });
运行结果

基本请求就是这样,配置做好,根据api定义好接口,配合Gson。请求完了就可以直接获得值了。
Get的动态参数
举个栗子
我们都知道url大多数都是拼接的,像我们查询天气的接口,就是动态传一个城市的名字。
http://op.juhe.cn/onebox/weather/query?cityname=深圳&key=您申请的KEY
默认cityname是深圳,后面就是我们需要拼接的
- WeatherApi1 
 2
 3
 4public interface WeatherApi { 
 @GET("onebox/weather/query?cityname=深圳")
 Call<WeatherDataBean> getWeather(@Query("key")String kry);
 }
这里可以看到,在Get的时候还是把连接的后半段传进去,但是在这里最后拼接的时候是一个key,所以在传入参数的前面加上Query
- 代码 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21- // WeatherDataApi 
 // Get的动态参数
 Retrofit retrofit = new Retrofit.Builder()
 .baseUrl("http://op.juhe.cn/")
 .addConverterFactory(GsonConverterFactory.create())
 .build();
 WeatherApi api = retrofit.create(WeatherApi.class);
 Call<WeatherDataBean> call = api.getWeather("4ea58de8a7573377cec0046f5e2469d5");
 // 异步
 call.enqueue(new Callback<WeatherDataBean>() {
 @Override
 public void onResponse(Call<WeatherDataBean> call, Response<WeatherDataBean> response) {
 String info = response.body().getResult().getData().getRealtime().getWeather().getInfo();
 mTextView.setText("深圳天气: " + info);
 }
 @Override
 public void onFailure(Call<WeatherDataBean> call, Throwable t) {
 }
 });
- 运行结果  
Get参数请求
举个栗子
例如我们的接口是直接传参的
//后面三个参数
Android可接受参数 | Android | iOS | 休息视频 | 福利 | 前端 | App
count 最大 50
page 是页数
这种类型又该如何操作呢?
- 假设我们直接传入的参数是page1 
 2
 3
 4public interface Gank2Api { 
 @GET("api/data/Android/10/{page}")
 Call<GankBean> getAndroidInfo(@Path("page") int page);
 }
在这里使用大括号做占位符,然后使用Path关键字,接着继续写代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//        Get参数请求
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://gank.io/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        Gank2Api api = retrofit.create(Gank2Api.class);
        api.getAndroidInfo(1).enqueue(new Callback<GankBean>() {
            @Override
            public void onResponse(Call<GankBean> call, Response<GankBean> response) {
                mTextView.setText(response.body().getResults().get(0).getDesc());
            }
            @Override
            public void onFailure(Call<GankBean> call, Throwable t) {
            }
        });
运行结果

Get参数拼接
| 1 | public interface WeatherApi2 { | 
Get后面传入的参数并没有像cityname一类的参数,但是有一个QueryMap,传入的是键值对1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//      Get参数拼接
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://op.juhe.cn/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        WeatherApi2 api = retrofit.create(WeatherApi2.class);
        Map<String, String> params = new HashMap<>();
        params.put("cityname","深圳");
        params.put("key","4ea58de8a7573377cec0046f5e2469d5");
        api.getWeather(params).enqueue(new Callback<WeatherDataBean>() {
            @Override
            public void onResponse(Call<WeatherDataBean> call, Response<WeatherDataBean> response) {
                mTextView.setText(response.body().getResult().getData().getRealtime().getWeather().getInfo());
            }
            @Override
            public void onFailure(Call<WeatherDataBean> call, Throwable t) {
            }
        });
运行结果

Post
| 1 | import retrofit2.Call; | 
这里POST的地址和之前的get也是一样的,这里返回一个Result是我们自己定义的结果类,Body是表示参数,我需要一个User,那我们的User就是1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class User {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
| 1 | public class Result { | 
调用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16User user = new User();
    user.setId(1);
    user.setName("lgl");
    api.postUser(user).enqueue(new Callback<Result>() {
        @Override
        public void onResponse(Call<Result> call, Response<Result> response) {
            if (response.body().getYes() == 0) {
                Toast.makeText(MainActivity.this, "成功", Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onFailure(Call<Result> call, Throwable t) {
        }
    });
我在这里传了一个user进去,细节不过就是id和name,如果请求成功,那就返回0,失败就是1,这里服务端定义,这样我们就POST完成了
Post提交表单
| 1 | @POST("user/edit") | 
直接调用方法1
2
3
4
5
6
7
8
9
10
11
12
13api.editUser(1, "liuguilin").enqueue(new Callback<Result>() {
        
        public void onResponse(Call<Result> call, Response<Result> response) {
            if (response.body().getYes() == 0) {
                Toast.makeText(MainActivity.this, "成功", Toast.LENGTH_SHORT).show();
            }
        }
        
        public void onFailure(Call<Result> call, Throwable t) {
        }
    });
RxJava + Retrofit2.0
举个栗子
登录,登录成功后获取到user_id,再去请求用户信息,这里应该是两个请求对吧,我们先去写好接口,这里我们先用常规的方法去获取:1
2
3
4
5@POST("user/login")
Call<User> login(@Field("username") String user, @Field("password") String password);
@GET("user/info")
Call<User> getUser(@Query("id") String id);
这里的两个接口,一个是登录,传参用户名和密码,还有一个是用id去查找用户信息的1
2
3
4
5
6Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("baseUrl")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
 api = retrofit.create(PostApi.class);
这里我们需要增加addCallAdapterFactory为我们后面的Rx做准备,然后我们调用两次1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28api.login("liuguilin", "748778890").enqueue(new Callback<User>() {
    @Override
    public void onResponse(Call<User> call, Response<User> response) {
        if (response.isSuccessful()) {
            String id = response.body().getUser_id();
            api.getUser(id).enqueue(new Callback<User>() {
                @Override
                public void onResponse(Call<User> call, Response<User> response) {
                    Toast.makeText(MainActivity.this, "id:" +
                                    response.body().getId()
                                    + "name:" + response.body().getName(),
                            Toast.LENGTH_SHORT).show();
                }
                @Override
                public void onFailure(Call<User> call, Throwable t) {
                }
            });
        }
    }
    @Override
    public void onFailure(Call<User> call, Throwable t) {
    }
});
RxJava写法
重新定义两个接口1
2
3
4
5@POST("user/login")
rx.Observable<User> loginForRX(@Body User user);
@GET("user/info")
rx.Observable<User> getUserForRX(@Query("id") String id);
这里的是伪代码,注意看使用方法1
2
3
4
5
6
7
8
9
10
11api.loginForRX(new User("liuguilin", "748778890")).flatMap(new Func1<User, Observable<User>>() {
    
    public Observable<User> call(User user) {
        return api.getUser(user.getUser_id());
    }
}).subscribe(new Action1<User>() {
    
    public void call(User user) {
        Toast.makeText(MainActivity.this, "name:" + user.getName(), Toast.LENGTH_SHORT).show();
    }
});
