Retrofit2+Rxjava2請(qǐng)求WebService(修訂版)

前言

之前寫(xiě)了一篇文章 Retrofit2+Okhttp3+Rxjava通過(guò)SOAP協(xié)議請(qǐng)求WebService 通過(guò)整合Retrofit,Okhttp,Rxjava來(lái)實(shí)現(xiàn)WebService的網(wǎng)絡(luò)訪問(wèn),但其中還有許多地方不夠完善,并沒(méi)有發(fā)揮出Rxjava的強(qiáng)大之處,因此在這里通過(guò)完善封裝,加入網(wǎng)絡(luò)請(qǐng)求的取消,避免內(nèi)存泄漏,使之更加簡(jiǎn)潔,方便使用。
這里只呈現(xiàn)出修改變動(dòng)的部分,不太明白的話可以先看之前的文章。

依賴

Rxjava使用2.0的(之前使用1.0)

    compile 'io.reactivex.rxjava2:rxjava:2.1.0'
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

新增Rxjava與Retrofit的適配器(Square官方提供的適配器目前僅支持Rxjava1)

compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

內(nèi)容

1.ServiceStore請(qǐng)求接口
使用了Rxjava與Retrofit的適配器,因此,返回類型變?yōu)镺bservable<ResponseBody>

public interface ServiceStore {
    
    @Headers({
            "Content-Type: text/xml; charset=utf-8",
            "SOAPAction: http://tempuri.org/NewsInquiry"
    })
    @POST("WebServices/EhomeWebservice.asmx")
    Observable<ResponseBody> getNews(@retrofit2.http.Body String str);

    @GET
    Observable<ResponseBody> download(@Url String fileUrl);

    @GET("http://gank.io/api/data/{type}/{pageSize}/{pageIndex}")
    Observable<ResultsEntity> getInfo(@Path("type") String type, @Path("pageSize") String pageSize, @Path("pageIndex") String pageIndex);
}

2.RequestManager請(qǐng)求管理者
移除execute()和doRequest()方法,對(duì)Retrofit進(jìn)行初始化配置,ServiceStore的創(chuàng)建移到RequestManager初始化,這就意味著所有的請(qǐng)求接口都要寫(xiě)在ServiceStore內(nèi)。

public class RequestManager {
    public final static int CONNECT_TIMEOUT = 10;
    public final static int READ_TIMEOUT = 20;
    public final static int WRITE_TIMEOUT = 10;
    public Retrofit mRetrofit;
    private static RequestManager mRequestManager;//管理者實(shí)例
    public OkHttpClient mClient;//OkHttpClient實(shí)例
    public ServiceStore mServiceStore;//請(qǐng)求接口
    private RequestManager() {
        init();
    }
    //單例模式,對(duì)提供管理者實(shí)例
    public static RequestManager getInstance() {
        if (mRequestManager == null) {
            synchronized (RequestManager.class) {
                if (mRequestManager == null) {
                    mRequestManager = new RequestManager();
                }
            }
        }
        return mRequestManager;
    }
    private void init(){
        Strategy strategy = new AnnotationStrategy();
        Serializer serializer = new Persister(strategy);
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
        builder.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS);
        builder.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS);
        builder.retryOnConnectionFailure(true);
        mClient = builder.build();
        mRetrofit = new Retrofit.Builder()
                .baseUrl(Constans.WEBSERVICE_URL)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(SimpleXmlConverterFactory.create(serializer))
                .client(mClient)
                .build();
        mServiceStore=mRetrofit.create(ServiceStore.class);
    }

    public interface onRequestCallBack{
        void onSuccess(String msg);
        void onError(String msg);
    }

}

3.新增ResultObserver類
該類實(shí)現(xiàn)Observer接口,對(duì)上游事件(請(qǐng)求結(jié)果)進(jìn)行解析,然后通過(guò)自定義接口進(jìn)行數(shù)據(jù)回調(diào)

public class ResultObserver implements Observer<ResponseBody> {
    private RequestManager.onRequestCallBack callBack;
    public ResultObserver( RequestManager.onRequestCallBack callBack){
        this.callBack=callBack;
    }
    @Override
    public void onSubscribe(@NonNull Disposable d) {

    }
    @Override
    public void onNext(@NonNull ResponseBody responseBody) {

        try {
            String res = responseBody.string();
            if (res == null) {
                callBack.onError("請(qǐng)求發(fā)生未知錯(cuò)誤");
                return;
            }

            if (res.contains("{") && res.contains("}")) {
                int startIndex = res.indexOf("{");
                int endIndex = res.lastIndexOf("}") + 1;
                String json = res.substring(startIndex, endIndex);
                callBack.onSuccess(json);
            }
        } catch (IOException e) {
            e.printStackTrace();
            callBack.onError(e.toString());
        }
    }

    @Override
    public void onError(@NonNull Throwable e) {
        callBack.onError(e.toString());
    }
    @Override
    public void onComplete() {

    }
}

4.請(qǐng)求參數(shù)拼裝

public class Node {
    //"<"節(jié)點(diǎn)轉(zhuǎn)義
    private static String toStart(String name){
        return "<"+name+">";
    }
    //">"節(jié)點(diǎn)轉(zhuǎn)義
    private static String toEnd(String name){
        return "</"+name+">";
    }
    //請(qǐng)求參數(shù)拼接
    public static String getRequestParams(String namespace, Map<String,String> map){
        if(map==null){
            map=new HashMap<>();
        }
        StringBuffer sbf=new StringBuffer();
        sbf.append(Node.toStart("Request"));
        for(Map.Entry<String,String> entry:map.entrySet()){
            sbf.append(Node.toStart(entry.getKey()));
            sbf.append(entry.getValue());
            sbf.append(Node.toEnd(entry.getKey()));
        }
        sbf.append(Node.toEnd("Request"));
        String str="<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
                "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" +
                "  <soap:Header>\n" +
                "    <Identify xmlns=\"http://tempuri.org/\">\n" +
                "      <UserName>"+ Constans.USERNAME+"</UserName>\n" +
                "      <PassWord>"+Constans.PASSWORD+"</PassWord>\n" +
                "    </Identify>\n" +
                "  </soap:Header>\n" +
                "  <soap:Body>\n" +
                "    <"+namespace+" xmlns=\"http://tempuri.org/\">\n" +
                "      <str>"+sbf.toString()+"</str>\n" +
                "    </"+namespace+">\n" +
                "  </soap:Body>\n" +
                "</soap:Envelope>";
        return str;
    }
}

5.請(qǐng)求示例
Rxjava2會(huì)返回一個(gè) Disposable,它是觀察者與被觀察者之間的一個(gè)開(kāi)關(guān),調(diào)用它的dispose()方法,下游將不會(huì)收到發(fā)送事件,可以在頁(yè)面銷毀時(shí)調(diào)用,避免執(zhí)行更新UI。
CompositeDisposable是Rxjava內(nèi)置的一個(gè)容器,用于保存 Disposable,在頁(yè)面銷毀時(shí)候調(diào)用它的clear方法即可

CompositeDisposable mCompositeDisposable= new CompositeDisposable();

private void getNews() {
        Map<String,String> map=new HashMap<>();
        map.put("PageSize",10+"");
        map.put("PageIndex",1+"");
        String request= Node.getRequestParams("NewsInquiry",map);
        Disposable disposable = RequestManager.getInstance()
                .mServiceStore
                .getNews(request)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new ResultObserver(new RequestManager.onRequestCallBack() {
                    @Override
                    public void onSuccess(String msg) {
                        tv_msg.setText(msg);
                    }
                    @Override
                    public void onError(String msg) {
                        tv_msg.setText(msg);
                    }
                }));
        mCompositeDisposable.add(imageDisposable);
}
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCompositeDisposable.clear();
    }

6.點(diǎn)擊“網(wǎng)絡(luò)請(qǐng)求”按鈕,結(jié)果如圖


請(qǐng)求結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,733評(píng)論 25 709
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 1. 絲塔芙 日用潔面乳 Cetaphil Daily Skin Cleanser $7/240ml 起泡度:★★...
    太陽(yáng)里的香腸貓閱讀 5,779評(píng)論 0 6
  • 石梯處淡綠的小草, 用惺忪的睡醒偷瞄我。 長(zhǎng)廊里微熏的小花, 用稚嫩的身姿仰視我。 他們的生命, 在裊裊的清風(fēng)里新...
    256acdf50527閱讀 376評(píng)論 0 0
  • 文|Sue She 朋友Y小姐電話QQ我,聲嘶力竭、痛苦不堪。于是就知道了今日大半天的時(shí)間都奉獻(xiàn)給她了。 幸福的感...
    天線鹿寶閱讀 567評(píng)論 3 1

友情鏈接更多精彩內(nèi)容