• Android Retrofit 2.0使用


    添加依赖

    app/build.gradle

    1
    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'

    接口调用

    1
    2
    3
    4
    5
    6
    Retrofit retrofit = new Retrofit.Builder()
    //这里建议:- Base URL: 总是以/结尾;- @Url: 不要以/开头
    .baseUrl("http://www.weather.com.cn/")
    .build();
    ApiStores apiStores = retrofit.create(ApiStores.class);
    Call<ResponseBody> call = apiStores.getWeather("101010100");

    如果@GET(“http://ip.taobao.com/service/getIpInfo.php"),则baseUrl无效。
    注意这个任务是网络任务,不要忘记给程序加入网络权限

    1
    <uses-permission android:name="android.permission.INTERNET" />

    同步调用

    1
    2
    3
    4
    5
    6
    7
    try {
    Response<ResponseBody> bodyResponse = call.execute();
    String body = bodyResponse.body().string();//获取返回体的字符串
    Log.i("wxl", "body=" + body);
    } catch (IOException e) {
    e.printStackTrace();
    }

    同步需要处理android.os.NetworkOnMainThreadException

    异步调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Response<ResponseBody> response) {
    try {
    Log.i("wxl", "response=" + response.body().string());
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
     
    @Override
    public void onFailure(Throwable t) {
    Log.i("wxl", "onFailure=" + t.getMessage());
    }
    });

    移除请求

    1
    call.cancel();

    接口参数

    Path

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
    * Call<T> get();必须是这种形式,这是2.0之后的新形式
    * 如果不需要转换成Json数据,可以用了ResponseBody;
    * 你也可以使用Call<GsonBean> get();这样的话,需要添加Gson转换器
    */
    public interface ApiStores {
    @GET("adat/sk/{cityId}.html")
    Call<ResponseBody> getWeather(@Path("cityId") String cityId);
    }

    Query

    如果链接是http://ip.taobao.com/service/getIpInfo.php?ip=202.202.33.33

    1
    2
    @GET("http://ip.taobao.com/service/getIpInfo.php")
    Call<ResponseBody> getWeather(@Query("ip") String ip);

    Body

    这是针对POST方式,如果参数是json格式,如:

    1
    2
    3
    4
    5
    6
    {
    "apiInfo": {
    "apiName": "WuXiaolong",
    "apiKey": "666"
    }
    }

    建立Bean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class ApiInfo {
    private ApiInfoBean apiInfo;
     
    public ApiInfoBean getApiInfo() {
    return apiInfo;
    }
     
    public void setApiInfo(ApiInfoBean apiInfo) {
    this.apiInfo = apiInfo;
    }
     
    public class ApiInfoBean {
    private String apiName;
    private String apiKey;
    //省略get和set方法
    }
    }

    代码调用

    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
    28
    29
    30
    31
    private void getCarType() {
    mRetrofit = new Retrofit.Builder()
    .baseUrl("http://WuXiaolong.me/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
    ApiStores apiStores = mRetrofit.create(ApiStores.class);
    ApiInfo apiInfo = new ApiInfo();
    ApiInfo.ApiInfoBean apiInfoBean = apiInfo.new ApiInfoBean();
    apiInfoBean.setApiKey("666");
    apiInfoBean.setApiName("WuXiaolong");
    apiInfo.setApiInfo(apiInfoBean);
    Call<ResponseBody> call = apiStores.getCarType(apiInfo);
    call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Response<ResponseBody> response) {
    String body = null;//获取返回体的字符串
    try {
    body = response.body().string();
    } catch (IOException e) {
    e.printStackTrace();
    }
    Log.i("wxl", "get=" + body);
    }
     
    @Override
    public void onFailure( Throwable t) {
     
    }
     
    });
    }

    ApiStores

    1
    2
    3
    4
    public interface ApiStores {
    @POST("client/shipper/getCarType")
    Call<ResponseBody> getCarType(@Body ApiInfo apiInfo);
    }

    JSON解析库

    Retrofit 2现在支持许多种解析方式来解析响应数据,包括Moshi,一个由Square创建的高效JSON解析库。

    添加gson依赖

    app/build.gradle

    1
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'

    jsonschema2pojo

    访问jsonschema2pojo,自动生成Java对象,如果你对gson还不熟悉,笔者建议你手动生成Java对象,感受下。

    这里如果选择Gson,生成的代码中存在@Generated注解,Android默认并没有javax.annotation library。如果你希望保留@Generated注解,需要添加如下的依赖。

    1
    compile 'org.glassfish:javax.annotation:10.0-b28'

    或者,你可以直接删除这个注解,完全没有问题。笔者当然不会加这个依赖啦。

    Gsonformat

    作用:Android studio插件,一般接口返回数据后要建立自己的bean,Gsonformat帮助你快速生成,不用一条一条去写。比jsonschema2pojo更加简单。
    安装步骤:Android studio-Settings-Plugins-搜Gsonformat-Install Plugin
    效果预览:

    实例代码

    依旧演示上面的天气:http://www.weather.com.cn/adat/sk/101010100.html

    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
    28
    public class WeatherJson {
    //weatherinfo需要对应json数据的名称,我之前随便写了个,被坑很久
    private Weatherinfo weatherinfo;
     
    public Weatherinfo getWeatherinfo() {
    return weatherinfo;
    }
     
    public void setWeatherinfo(Weatherinfo weatherinfo) {
    this.weatherinfo = weatherinfo;
    }
    //city、cityid必须对应json数据的名称,不然解析不了
    public class Weatherinfo {
    private String city;
    private String cityid;
    private String temp;
    private String WD;
    private String WS;
    private String SD;
    private String WSE;
    private String time;
    private String isRadar;
    private String Radar;
    private String njd;
    private String qy;
    //这里省略get和set方法
    }
    }

    ApiStores:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class AppClient {
    static Retrofit mRetrofit;
     
    public static Retrofit retrofit() {
    if (mRetrofit == null) {
    mRetrofit = new Retrofit.Builder()
    .baseUrl("http://www.weather.com.cn/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
    }
    return mRetrofit;
    }
     
    public interface ApiStores {
    @GET("adat/sk/{cityId}.html")
    Call<WeatherJson> getWeather(@Path("cityId") String cityId);
    }
    }

    调用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    private void getWeather() {
    AppClient.ApiStores apiStores = AppClient.retrofit().create(AppClient.ApiStores.class);
    Call<WeatherJson> call = apiStores.getWeather("101010100");
    call.enqueue(new Callback<WeatherJson>() {
    @Override
    public void onResponse(Response<WeatherJson> response) {
    Log.i("wxl", "getWeatherinfo=" + response.body().getWeatherinfo().getCity());
    }
     
    @Override
    public void onFailure(Throwable t) {
     
    }
    });
    }

    经Gson转换器,Call<ResponseBody>换成自己要写的Call<WeatherJson>

    RxJava

    依赖以下:

    1
    2
    compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta3'
    compile 'io.reactivex:rxandroid:1.0.1'

    增加addCallAdapterFactory

    1
    2
    3
    4
    5
    Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://api.nuuneoi.com/base/")
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
    .build();

    ApiStores

    1
    2
    @GET("adat/sk/{cityId}.html")
    Observable<WeatherJson> getWeatherRxjava(@Path("cityId") String cityId);

    subscribe部分的代码在Schedulers.io被调用,需要把observeOn(AndroidSchedulers.mainThread())添加到链表中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    private void getWeatherRxjava() {
    AppClient.ApiStores apiStores = AppClient.retrofit().create(AppClient.ApiStores.class);
    Observable<WeatherJson> observable = apiStores.getWeatherRxjava("101010100");
    observable.subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Observer<WeatherJson>() {
    @Override
    public void onCompleted() {
    Log.i("wxl", "onCompleted");
    }
     
    @Override
    public void onError(Throwable e) {
    Log.i("wxl", "e=" + e.getMessage());
    }
     
    @Override
    public void onNext(WeatherJson weatherJson) {
    Log.i("wxl", "getWeatherinfo=" + weatherJson.getWeatherinfo().getCity());
    }
    });
     
    }

    Retrofit源码解析

    另见白瓦力的博客,分析的很到位,解释了0、Retrofit 是什么,1、Retrofit 怎么用,2、Retrofit的原理是什么,3、一些总结。
    博客地址:http://bxbxbai.github.io/2015/12/13/retrofit2/
    PS:十分感谢白瓦力,他教会我们如何去查看源码的一种有效方法,debug一步步去跟源码。

    附录

    retrofit官方文档
    用 Retrofit 2 简化 HTTP 请求
    使用Retrofit请求API数据
    Retrofit2 更新指南
    RESTful API 设计指南

    专注,认真,坚持,分分秒秒,每天进步一点点
  • 相关阅读:
    【leetcode】92. 反转链表 II
    【leetcode】91. 解码方法
    【leetcode】89. 格雷编码
    【leetcode】86. 分隔链表
    【leetcode】82. 删除排序链表中的重复元素 II
    为什么选择react
    React 全家桶实现后台管理界面
    前后端同构
    浅谈React前后端同构防止重复渲染
    由React引发的前后端分离架构的思考
  • 原文地址:https://www.cnblogs.com/jingzhi/p/6780644.html
Copyright © 2020-2023  润新知