RxJava
RxJava 在 GitHub 主頁上的自我介紹是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫)。這就是 RxJava ,概括得非常精准。當然這是比較官網的解釋,也是一頭霧水,以我的理解,其實就是觀察者模式,觀察者與被觀察者,類似Android里面的button點擊事件。用來實現異步操作,Android里面有很多方法實現異步操作,RxJava的優勢就是很簡潔,代碼看着很舒服,像我們這種有代碼潔癖的人來說簡直就是福音,更重要的是隨着項目的開展,產品的需求迭代,依然能保持簡潔。當然網上有很多RxJava的博文,一些大神講解的也是非常的細,比我講的那是好多了,我就不一一說了,推薦幾篇文章。
RxJava:https://gank.io/post/560e15be2dca930e00da1083#toc_1
Retrofit
Retrofit是一款針對Android網絡請求的開源框架,它與okhttp一樣出自Square公司。Rotrofit2.0的網絡框架全部交給了okhttp來實現,Android N之后Apache的httpclient已經被Google從SDK中移除,Okhttp則成功上位。Retrofit的網絡請求實現風格與URLconnection和httpClient有較大的差別。創建請求的時候需要先創建基於注解的服務接口(不了解的可以先了解一下注解),進行網絡請求的時候再通過Retrofit.creat()方法來創建請求。以我的理解其實就是對Okhttp進行了一層的封裝,而且retrofit可以很好的搭配RxJava使用,所以說retrofit和RxJava更配哦。。
看完上述兩篇文章還不是很懂的,咱們直接來實例操作:在gradle引入jar包
compile 'io.reactivex.rxjava2:rxjava:2.2.19' //RxJava2依賴
compile 'io.reactivex.rxjava2:rxandroid:2.1.1' //RxAndroid依賴,切換線程
compile 'com.squareup.retrofit2:converter-gson:2.3.0' // 必要依賴,解析json字符所用
compile 'com.squareup.okhttp3:okhttp:3.1.2' // 網絡請求必要依賴
compile 'com.squareup.retrofit2:adapter-rxjava2:2.5.0' // rxjava2和retrofit2的適配器
接口聲明、統一管理接口:ApiServiceManager
其中的token、validateCode是我們自定義的數據接收類,根據返回的數據格式來定義
package com.org.huanjianmvp.Internet; import com.org.huanjianmvp.Domain.token; import com.org.huanjianmvp.Domain.validateCode; import io.reactivex.Observable; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.POST; /** * 接口聲明、統一管理接口 * Created by Administrator on 2020/8/20. */ public interface ApiServiceManager { /**【刷新token請求】**/ @POST("oauth/token") @FormUrlEncoded Observable<token> requestToken(@Field("grant_type") String grant_type,@Field("client_id") String client_id, @Field("client_secret") String client_secret,@Field("refresh_token") String refresh_token); /**【請求驗證碼】**/ @GET("code/image") Observable<validateCode> requestCode(); }
就拿 validateCode 作為例子說明:這是一個接收驗證碼的接口返回數據,只是拿來測試的,下面是根據返回數據格式來定義的一個對象
package com.org.huanjianmvp.Domain; import android.util.Log; /** * Created by Administrator on 2020/9/28. */ public class validateCode { private int code; private String msg; private int count; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } class data{ public String imageKey; private String imageCode; public String getImageKey() { return imageKey; } public void setImageKey(String imageKey) { this.imageKey = imageKey; } public String getImageCode() { return imageCode; } public void setImageCode(String imageCode) { this.imageCode = imageCode; } } public void dataLog(){ Log.e("code",code + "\t\tmsg:" + msg + "\t\tcount:" + count ); } }
返回的數據類型為:
Observer封裝、可在各個方法中做一些封裝或數據處理:
package com.org.huanjianmvp.Internet; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; /** * Observer封裝、可在各個方法中做一些封裝或數據處理 * 由子類來實現抽象方法 * Created by Administrator on 2020/8/20. */ public abstract class ObserverManager<T> implements Observer<T> { @Override public void onSubscribe(Disposable d) { onDisposable(d); } @Override public void onNext(T t) { onSuccess(t); } @Override public void onComplete() { onFinish(); } @Override public void onError(Throwable e) { onFail(e); } public abstract void onSuccess(T t); //調用成功 public abstract void onFail(Throwable throwable); //調用失敗或者報錯 public abstract void onFinish(); //調用完成 public abstract void onDisposable(Disposable disposable); //調用前准備工作 }
Retrofit管理器,保證Retrofit在類中只有一個實例,避免請求體的多次創建:
Retrofit.client(client)如果不需要跳過https校驗可以去掉
package com.org.huanjianmvp.Internet; import javax.net.ssl.SSLContext; import okhttp3.OkHttpClient; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; /** * Retrofit管理器,保證Retrofit在類中只有一個實例,避免請求體的多次創建 * 封裝Retrofit * Created by Administrator on 2020/8/20. */ public class RetrofitManager { private volatile static RetrofitManager retrofitManager; private Retrofit retrofit; //沒有參數的單例模式 public static RetrofitManager getRetrofitManager(){ if (retrofitManager == null){ synchronized (RetrofitManager.class){ retrofitManager = new RetrofitManager(); } } return retrofitManager; } //沒有參數的構造方法 public RetrofitManager(){ initRetrofitManager(); } //構造方法創建Retrofit實例 private void initRetrofitManager(){ // 09.29 跳過https校驗客戶端配置 SSLContext sslContext = IgnoreHttpsValidate.getSSLContext(); OkHttpClient client = new OkHttpClient.Builder() .hostnameVerifier(IgnoreHttpsValidate.doNotVerifier) .sslSocketFactory(sslContext.getSocketFactory()) //得到sslSocketFactory實例 設置sllsocketfactory .build(); retrofit = new Retrofit.Builder() .baseUrl("https://47.97.178.108:8090/") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //添加Rx轉換器 .addConverterFactory(GsonConverterFactory.create()) //添加Gson轉換器 .client(client) // 09/29,設置客戶端的請求 .build(); } //獲取網絡接口實例 public ApiServiceManager getApiService(){ return retrofit.create(ApiServiceManager.class); } }
設置相關https請求訪問忽略校驗:
package com.org.huanjianmvp.Internet; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; /** * 設置相關https請求訪問忽略校驗 * Created by Administrator on 2020/9/29. */ public class IgnoreHttpsValidate { /** * 獲取Https的證書 * 09/29 * context Activity(fragment)的上下文 * @return SSL的上下文對象 */ public static SSLContext getSSLContext() { SSLContext ssLContext; TrustManager[] trustManagers; X509TrustManager x509TrustManager; try { x509TrustManager = new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } }; trustManagers = new TrustManager[]{ x509TrustManager }; //生成trustmanager數組 ssLContext = SSLContext.getInstance("TLS"); //得到sslcontext實例。SSL TSL 是一種https使用的安全傳輸協議 ssLContext.init(null, trustManagers, new SecureRandom()); //初始化sslcontext 信任所有證書 (官方不推薦使用) return ssLContext; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return null; } //跳過Hostname,直接返回true static HostnameVerifier doNotVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; }
接口調用:在需要處理的地方調用接口即可
Observable<validateCode> observable = RetrofitManager.getRetrofitManager().getApiService().requestCode(); observable.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new ObserverManager<validateCode>() { @Override public void onSuccess(validateCode validateCode) { validateCode.dataLog(); } @Override public void onFail(Throwable throwable) { Log.e("Throwable",throwable.toString()); } @Override public void onFinish() { Log.e("請求驗證碼結果","完成"); } @Override public void onDisposable(Disposable disposable) { } });
結果: