是時候來了解一波Retrofit2了。

之前的網絡請求一直是用的okhttp,這段時間瞭解了一下retrofit2,發現比自己封裝的okhttp靈活很多,他的所有請求方式都是用接口實現,不像okhttp那樣,萬一想獲取一個新的callback,又得重新封裝一個方法。
由於retrofit2默認用okhttp請求網絡,所以已經不需要再導入okhttp了。
如果返回的類型是Call,那麼就響應OkHttp的callback
可以配合RxJava使用,返回的類型設置爲Oservable。
導包:

    compile 'io.reactivex:rxjava:1.1.3'
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'com.squareup.retrofit2:retrofit:2.0.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:converter-scalars:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
    compile 'com.jakewharton:butterknife:7.0.1'

在這裏遇到一些坑,如果下面三個少一個,返回他不支持的結果時,就會崩潰,這也是上面爲什麼會導那麼多包的原因。

   private static Retrofit getRetrofit(String url) {
        return new Retrofit.Builder().baseUrl(url)
                //增加返回值爲String的支持
                .addConverterFactory(ScalarsConverterFactory.create())
                //增加返回值爲Gson的支持(以實體類返回)
                .addConverterFactory(GsonConverterFactory.create())
                //增加返回值爲Oservable<T>的支持
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

GET請求:
http://wthrcdn.etouch.cn/weather_mini?city=深圳

public interface IWeather {
        @GET("/weather_mini")
        Observable<Weather> getWeather(@Query("city") String city);
}
 public static final String url_weather = "http://wthrcdn.etouch.cn";
 public static IWeather getIWeather() {
        return getRetrofit(url_weather).create(IWeather.class);
    }
    HttpUtil.getIWeather().getWeather("深圳")
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<Weather>() {
                            @Override
                            public void call(Weather weather) {
                                tv.setText(weather.getData().getGanmao());
                            }
                        });

Post請求:
根據後臺,Multipart或FormUrlEncoded,如果不知道最好兩種都試一下,我在這裏也是遇了大坑,如果方式錯了,根本就post不上去。。
Multipart(這個是用的自己的服務器,後面的人看到這篇博客可能這個api就用不了了)
http://122.114.38.95:8857
參數是 action , 如果action=banner就可以返回正確結果否則錯誤結果

  @Multipart
    @POST("/")
    Observable<String> getBanner(@Part("action") String action);
public static final String url_bannertest = "http://122.114.38.95:8857";
public static IBannerTest getBanner() {
        return getRetrofit(url_bannertest).create(IBannerTest.class);
    }
HttpUtil.getBanner().getBanner("banner")
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<String>() {
                            @Override
                            public void call(String s) {
                                tv.setText(s);
                            }
                        });

FormUrlEncoded:(借用了w3c的教程裏的url)
http://www.w3school.com.cn/ajax/demo_post2.asp
參數 fname,lname

  @FormUrlEncoded
    @POST("/ajax/demo_post2.asp")
    Observable<String> postW3c(@Field("fname") String fname, @Field("lname") String lname);
 public static final String w3c_url = "http://www.w3school.com.cn";
 public static IW3c getIW3C() {
        return getRetrofit(w3c_url).create(IW3c.class);
    }
 HttpUtil.getIW3C().postW3c("Long","Hoyn")
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<String>() {
                            @Override
                            public void call(String s) {
                                tv.setText(s);
                            }
                        });

post上傳圖片:
在這裏是用了image++的接口。
http://apicn.imageplusplus.com/analyze?
參數:api_key,api_secret, img

    @Multipart
    @POST("/analyze")
    Observable<String> upLoadImage( @Part("api_key") String api_key, @Part ("api_secret") String api_secret,@Part MultipartBody.Part file );
 public static final String imagepp_url = "http://apicn.imageplusplus.com";
 public static IImagePP getIImagePP() {
        return getRetrofit(imagepp_url).create(IImagePP.class);
    }

 public static MultipartBody.Part postFileParams(String key, File file) {
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        return MultipartBody.Part.createFormData(key, file.getName(), fileBody);
    }
File file = new File(Environment.getExternalStorageDirectory()+"/123.png");
                HttpUtil.getIImagePP().upLoadImage("c1a2b3ab56a2f218aed9b2ab3c16ce88","be8318b73cef1c2bcafb6c8a77922436",HttpUtil.postFileParams("img", file))
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<String>() {
                            @Override
                            public void call(String s) {
                                tv.setText(s);
                            }
                        });
private static Retrofit getRetrofit(String url) {
        return new Retrofit.Builder().baseUrl(url)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

上面說到了Retrofit加入了3句。
ScalarsConverterFactory是支持返回String類型
GsonConverterFactory是支持返回實體類。
RxJavaCallAdapterFactory是支持返回rxJava的Observable。

上面的例子Get請求用到了GsonConverterFactory和RxJavaCallAdapterFactory。
Post用到了ScalarsConverterFactory和RxJavaCallAdapterFactory
少一個都會蹦,所以大家用retrofit需要注意這一點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章