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 + "\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) {
                    }
                });

 

結果:


 
 
 


  
  


免責聲明!

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



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