RxJava和Retrofit的簡單使用


在最近做的項目中,因為頻繁用到網絡請求,所以使用了現在比較流行的框架RxJava和Retrofit來代替之前的Okhttp的繁瑣請求。

我這邊寫的比較簡單,自己在小項目中更使用的,如果需要深入研究,進行一些封裝的,管理RxJava生命周期的,請移步http://p.codekk.com/detail/Android/RuffianZhong/Rx-Mvp。

retrofit是用來做網絡請求操作,RxJava是用來切換線程、轉換數據操作的。

首先第一步,使用三方的框架,肯定是先添加依賴包。項目中用的Rxjava2.0、retrofit2.0,而且Rxjava2.0和Rxjava1.0並不兼容,所以使用起來需要注意。添加一下依賴。

compile "com.squareup.retrofit2:retrofit:$rootProject.versions.libRetrofit"
compile "com.squareup.retrofit2:converter-gson:$rootProject.versions.libRetrofit"
compile "com.squareup.retrofit2:adapter-rxjava2:$rootProject.versions.libRetrofit"
compile "com.squareup.okhttp3:okhttp:$rootProject.versions.libOkhttp"
compile "com.squareup.okhttp3:logging-interceptor:$rootProject.versions.libOkhttp"
compile "io.reactivex.rxjava2:rxjava:$rootProject.versions.libRxJava"
compile "io.reactivex.rxjava2:rxandroid:$rootProject.versions.libRxAndroid"

第二步,創建一個Api實例  用來獲取接口的請求對象    在init()方法中通過baseUrl或得到Retrofit對象,  請求方法等都是放在接口中,接口與retrofit關聯在getNetDemo()方法中實現。

 

public class NetDemoApi {
private static NetDemoApi nInstance = new NetDemoApi();
private Retrofit mRequestDemo;
//baseUrl是每一個網絡請求的前段,但必須是以 “/”結尾
private String mRequestDemoBaseUrl = "www.baidu.com/";
public static NetDemoApi getInstance(){
return nInstance;
}
private NetDemoApi(){
init();
}

private void init() {
//這一步就把baseurlRetrofit關聯了起來,生成Retrofit對象
mRequestDemo = configure(mRequestDemoBaseUrl);
}

private NetDemo getNetDemo(){
return mRequestDemo.create(NetDemo.class);
}

//配置retrofit
private Retrofit configure(String baseUrl){
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
WLog.i(message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//這只網絡請求的攔截器 如果需要獲取到響應頭等相應信息,在此處就可以獲得 如果不需要可以不寫
builder.networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
Headers headers = response.headers();
List<String> cookies = headers.values("Set-Cookie");
Session session = Session.getInstance();
session.setCookies(Utils.getCookie(cookies));
Log.d(getClass().getSimpleName(),"設置cookie " + session.getCookies());
return response;
}
});
builder.addInterceptor(logging);
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(40, TimeUnit.SECONDS);
OkHttpClient client = builder.build();
return new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
//這是rxjava的轉換器,這個是rxjava2的默認適配器工廠,如果我們需要轉換成bean,可以添加gson的轉換器,直接添加就可以,需要添加依賴包
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
}

第三步,寫實現的接口,這個接口中,才是我們需要請求的路徑  如下   @get 就是一個get請求的方法,     @post就是一個post請求

@url  是直接傳入一個已知的URl進去,直接請求Url,而且跟baseUrl無關,不會跟baseUrl進行拼接;

@Query 就是在URl后面進行鍵值對的拼接,如下  tip傳入1 ,就會把 tip=1 拼接到loginicon=true的后面,get和post請求都是這樣拼接。

@Path 就是把傳入的字符串直接傳入注解中{uuid}中的位置處;

@body 是post請求時,傳入的requestBody對象;

@Header  可以給網絡請求添加請求頭信息,添加Cookie就寫cookie,@Header("Cookie") String cookie,

以上傳入的url參數都會和baseUrl進行拼接,得到一個完整的Url去進行網絡請求(除了@url)。

返回的就是Observable對象,我們調用此方法后,獲得observable對象,接下來用Rxjava進行數據解析,篩選。

public interface NetDemo {
@GET
Observable<ResponseBody> requestDemo(@url String url);
   
  @GET("cgi-bin/mmwebwx-bin/login?loginicon=true")
  Observable<ResponseBody> requestScanResult(@Query("tip") int tip,
  @Query("uuid") String uuid,
  @Query("r") String r,
  @Query("_") String p);

  @POST("qrcode/{uuid}")
  Observable<ResponseBody> requestGenQRCode(@Path("uuid") String uuid,
  @Body RequestBody body);
  @POST("cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN")
  public Observable<ResponseBody> webwxstatusnotify(@Query("pass_ticket") String passTicket,
   @Header("Cookie") String cookie,
   @Body RequestBody body);

}

第四步,在代碼中進行網絡請求,

 

Observable<ResponseBody> observable = WeChatNetApi.getInstance().getLoginInfo().requestLoginInfo(url);      //返回Observable對象
observable.subscribeOn(Schedulers.io())                                           //進行網絡請求是在那個線程 io 就是在子線程
     .map(new Function<ResponseBody, Bitmap>() {                                 //可以通過map進行轉換,把結果轉換為一個我們需要使用的類型(如demo,返回一個bitmap類型)
    @Override
     public Bitmap apply(@io.reactivex.annotations.NonNull
   ResponseBody responseBody) {
   return BitmapFactory.decodeStream(responseBody.byteStream());
      }
    })
    .flatMap(new Function<String, ObservableSource<Bitmap>>() {                         //還可以通過flatMap轉化為Observable對象,轉換為Observable對象后,還可以繼續進行轉換操作,直到我們需要的類型
     @Override
     public ObservableSource<Bitmap> apply(
     @io.reactivex.annotations.NonNull String uuid) {
     return genQRCode(uuid);
     }
    }
    .filter(new Func1<Community, Boolean>() {                                     //只有返回true,才會繼續向下走,如果返回是false,就不會繼續向下走
      @Override
      public Boolean call(Community community) {
        return community.houses.size()>10;
       }
     })
 .observeOn(AndroidSchedulers.mainThread())                                    //網絡請求結束,切換回主線程,進行數據處理,或者顯示的操作
    .subscribe(new Observer<ResponseBody>() {                                  //轉換結束,得到了我們需要的數據,進行顯示,先切換到主線程
    @Override
     public void onSubscribe(Disposable d) {
      
     }
    @Override
    public void onNext(ResponseBody body) {                                 //訂閱后subscribe會執行的方法
     messageActivity.returnTextInfo(asJsonObject, l);
     }
    @Override
    public void onError(Throwable e) {                                    //如果流程中有報錯,會走到此

    }
    @Override
    public void onComplete() {                                         //onNext之后,如果還有后續的動作,可以在此繼續,onnext后會調用complete;

    }
    });



.doOnNext(new Consumer<ResponseBody>() {                                   //doOnNext 直接訂閱是一個偷懶的寫法,這樣寫代碼比較簡潔,而且這一步操作完之后,我也不需要繼續任何操作
@Override
public void accept(@io.reactivex.annotations.NonNull ResponseBody body) throws Exception {
handleLoginInfoResponse(url,body);
}
}).subscribe();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM