Android Retrofit 2.0使用

pugl9310 8年前發布 | 16K 次閱讀 Retrofit Android開發 移動開發

實例帶你了解Retrofit 2.0的使用,分享目前開發Retrofit遇到的坑和心得。

添加依賴

app/build.gradle

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

聲明接口

 /**
 * 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);
}

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

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

接口調用

 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無效。

注意這個任務是網絡任務,不要忘記給程序加入網絡權限

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

同步調用

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

同步需要處理android.os.NetworkOnMainThreadException

異步調用

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

移除請求

call.cancel();

JSON解析庫

Retrofit 2現在支持許多種解析方式來解析響應數據,包括Moshi,一個由Square創建的高效JSON解析庫。

添加gson依賴

app/build.gradle

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

jsonschema2pojo

訪問 jsonschema2pojo ,自動生成Java對象,如果你對gson還不熟悉,筆者建議你手動生成Java對象,感受下。

這里如果選擇Gson,生成的代碼中存在@Generated注解,Android默認并沒有javax.annotation library。如果你希望保留@Generated注解,需要添加如下的依賴。

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

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:

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

調用:

 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

依賴以下:

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

增加addCallAdapterFactory

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

ApiStores

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

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

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

    }

來自: http://www.jianshu.com/p/c213d9ec6c9b

 

 本文由用戶 pugl9310 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!