实例带你了解Retrofit 2.0的使用,分享目前开发Retrofit遇到的坑和心得

来源:互联网 发布:网络双生是什么意思 编辑:程序博客网 时间:2024/05/17 09:19

添加依赖

app/build.gradle

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

接口调用

123456
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" />

同步调用

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

同步需要处理android.os.NetworkOnMainThreadException

异步调用

123456789101112131415
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

123456789
 /** * 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

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

Body

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

123456
{    "apiInfo": {        "apiName": "WuXiaolong",        "apiKey": "666"    }}

建立Bean

1234567891011121314151617
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方法       }   }

代码调用

12345678910111213141516171819202122232425262728293031
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

1234
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

12345678910111213141516171819202122232425262728
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:

123456789101112131415161718
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);    }}

调用:

123456789101112131415
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

依赖以下:

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

增加addCallAdapterFactory

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

ApiStores

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

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

1234567891011121314151617181920212223
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());                   }               });   }
0 1
原创粉丝点击