Android Retrofit 2.0使用

pugl9310 9年前
   <p>实例带你了解Retrofit 2.0的使用,分享目前开发Retrofit遇到的坑和心得。</p>    <h2>添加依赖</h2>    <p>app/build.gradle</p>    <pre>  <code class="language-java">compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'</code></pre>    <h2>声明接口</h2>    <pre>  <code class="language-java"> /**   * 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);  }</code></pre>    <p>如果链接是 <a href="/misc/goto?guid=4959674392668334686" rel="nofollow,noindex">http://ip.taobao.com/service/getIpInfo.php?ip=202.202.33.33</a></p>    <pre>  <code class="language-java"> @GET("http://ip.taobao.com/service/getIpInfo.php")      Call<ResponseBody> getWeather(@Query("ip") String ip);</code></pre>    <h2>接口调用</h2>    <pre>  <code class="language-java"> 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");</code></pre>    <p>如果@GET(" <a href="/misc/goto?guid=4959674392755674413" rel="nofollow,noindex">http://ip.taobao.com/service/getIpInfo.php"),则baseUrl无效。</a></p>    <p>注意这个任务是网络任务,不要忘记给程序加入网络权限</p>    <pre>  <code class="language-java"><uses-permission android:name="android.permission.INTERNET" /></code></pre>    <h2>同步调用</h2>    <pre>  <code class="language-java">  try {              Response<ResponseBody> bodyResponse = call.execute();              String body = bodyResponse.body().string();//获取返回体的字符串              Log.i("wxl", "body=" + body);          } catch (IOException e) {              e.printStackTrace();          }</code></pre>    <p>同步需要处理android.os.NetworkOnMainThreadException</p>    <h2>异步调用</h2>    <pre>  <code class="language-java">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());              }          });</code></pre>    <h2>移除请求</h2>    <pre>  <code class="language-java">call.cancel();</code></pre>    <h2>JSON解析库</h2>    <p>Retrofit 2现在支持许多种解析方式来解析响应数据,包括Moshi,一个由Square创建的高效JSON解析库。</p>    <h2>添加gson依赖</h2>    <p>app/build.gradle</p>    <pre>  <code class="language-java">compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'</code></pre>    <h2>jsonschema2pojo</h2>    <p>访问 <a href="/misc/goto?guid=4958832210121601500" rel="nofollow,noindex">jsonschema2pojo</a> ,自动生成Java对象,如果你对gson还不熟悉,笔者建议你手动生成Java对象,感受下。</p>    <p><img src="https://simg.open-open.com/show/41987c6b26ddb138f457a90f16641e8a.png"></p>    <p>这里如果选择Gson,生成的代码中存在@Generated注解,Android默认并没有javax.annotation library。如果你希望保留@Generated注解,需要添加如下的依赖。</p>    <pre>  <code class="language-java">compile 'org.glassfish:javax.annotation:10.0-b28'</code></pre>    <p>或者,你可以直接删除这个注解,完全没有问题。笔者当然不会加这个依赖啦。</p>    <h2>Gsonformat</h2>    <p>作用:Android studio插件,一般接口返回数据后要建立自己的bean,Gsonformat帮助你快速生成,不用一条一条去写。比jsonschema2pojo更加简单。</p>    <p>安装步骤:Android studio-Settings-Plugins-搜Gsonformat-Install Plugin</p>    <p>效果预览:</p>    <p><img src="https://simg.open-open.com/show/4ec228dd7b81405568515f208261b525.gif"></p>    <h2>实例代码</h2>    <p>依旧演示上面的天气: <a href="/misc/goto?guid=4959674392861304532" rel="nofollow,noindex">http://www.weather.com.cn/adat/sk/101010100.html</a></p>    <pre>  <code class="language-java">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方法      }  }</code></pre>    <p>ApiStores:</p>    <pre>  <code class="language-java">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);      }  }</code></pre>    <p>调用:</p>    <pre>  <code class="language-java"> 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) {                }          });      }</code></pre>    <p>经Gson转换器, Call<ResponseBody> 换成自己要写的 Call<WeatherJson></p>    <h2>RxJava</h2>    <p>依赖以下:</p>    <pre>  <code class="language-java">compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta3'  compile 'io.reactivex:rxandroid:1.0.1'</code></pre>    <p>增加addCallAdapterFactory</p>    <pre>  <code class="language-java">Retrofit retrofit = new Retrofit.Builder()          .baseUrl("http://api.nuuneoi.com/base/")          .addConverterFactory(GsonConverterFactory.create())          .addCallAdapterFactory(RxJavaCallAdapterFactory.create())          .build();</code></pre>    <p>ApiStores</p>    <pre>  <code class="language-java"> @GET("adat/sk/{cityId}.html")   Observable<WeatherJson> getWeatherRxjava(@Path("cityId") String cityId);</code></pre>    <p>subscribe部分的代码在Schedulers.io被调用,需要把observeOn(AndroidSchedulers.mainThread())添加到链表中。</p>    <pre>  <code class="language-java"> 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());                      }                  });        }</code></pre>    <p>来自: <a href="/misc/goto?guid=4959674392945861148" rel="nofollow">http://www.jianshu.com/p/c213d9ec6c9b</a></p>    <p> </p>