zoukankan      html  css  js  c++  java
  • Android-----RxJava2 + retrofit2实现网络请求

    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) {
                        }
                    });
    结果:


     
     
     


      
      
  • 相关阅读:
    zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for {root.path}
    IDEA对新建java线程池的建议
    Hbase配置WEB UI界面
    Tomcat清理日志文件无法立即释放磁盘空间
    Tomcat多应用启动报错:org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load [].
    Soliworks 2016建模细节总结(1)
    关于自学C语言开始时应该注意的问题分享—未完待续......
    Word或者WPS里证件照的背景底色和像素调整
    Linux命令大全(非常全,史上最全)
    Android项目结构介绍
  • 原文地址:https://www.cnblogs.com/xiobai/p/13730169.html
Copyright © 2011-2022 走看看