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 + " msg:" + msg + " count:" + 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) { } });
结果: