1. 程式人生 > >記錄使用retrofit和rejava的初步使用

記錄使用retrofit和rejava的初步使用

    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'
    implementation 'com.android.support:support-v4:27.1.1'
    implementation 'com.android.support:cardview-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'//原生巢狀佈局
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.jakewharton:butterknife:8.8.1'//註解模式 1
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'//註解模式 2
    implementation 'com.yanzhenjie.nohttp:okhttp:1.1.9'//請求網路框架
    implementation 'com.github.bumptech.glide:glide:4.6.1'//圖片載入框架
    implementation 'com.cjj.materialrefeshlayout:library:1.3.0'//上下拉重新整理

    implementation 'com.github.xiaoyanger0825:NiceVieoPlayer:v2.2'//視訊播放框架1
    implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'//視訊播放框架2


    implementation 'com.zaaach:toprightmenu:1.1.2'//右上角popwindow

    implementation 'com.squareup.retrofit2:retrofit:2.1.0'//使用網路框架
    implementation 'com.squareup.okhttp3:okhttp:3.3.1'//使用網路請求執行器
    implementation 'com.squareup.retrofit2:converter-gson:2.1.0'//資料轉換器

    implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'// 銜接 Retrofit & RxJava

    implementation 'io.reactivex.rxjava2:rxjava:2.0.1'//網路請求介面卡
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'//網路請求介面卡

 

例子一實體類:

import java.util.List;

public class GankBean {

    /**
     * error : false
     * results : [{"_id":"5be404e49d21223dd88989d3","createdAt":"2018-11-08T09:41:56.840Z","desc":"微博,微信相簿效果,微信視訊拖放效果","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno5tb0h2g308w0g01l3","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno5xiiyrg308w0g0npi"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"web","type":"Android","url":"https://github.com/moyokoo/Diooto","used":true,"who":"miaoyj"},{"_id":"5bf2281f9d21223ddba8ca16","createdAt":"2018-11-19T03:03:59.86Z","desc":"Android RecyclerView Swipe Helper,用於處理每個方向的多個操作。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno63iuwng30aw07o4qs"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/bufferapp/MultiActionSwipeHelper","used":true,"who":"lijinshanmx"},{"_id":"5bf67e5b9d21223dd8898a01","createdAt":"2018-11-28T03:40:19.457Z","desc":"彩色二維碼。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno81ar12j31lk0rxq6s"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/jabcode/jabcode","used":true,"who":"galois"},{"_id":"5bf8bad89d21223dd8898a08","createdAt":"2018-11-28T04:22:55.510Z","desc":"狀態切換,讓View狀態的切換和Activity徹底分離開。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno82s497j30k00zkgmt","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno836mamj30k00zk0t4","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno83elg8j30k00zk74n","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8a4t79j30k00zkaau","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8afptjj30u01hc406"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"web","type":"Android","url":"https://github.com/yangchong211/YCStateLayout","used":true,"who":"瀟湘劍雨"},{"_id":"5bfdef389d212230a505d139","createdAt":"2018-11-28T03:41:35.737Z","desc":"一個輕量級版本更新彈窗。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8bhivcj308c0goaac"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"web","type":"Android","url":"https://github.com/yangchong211/YCUpdateApp","used":true,"who":"瀟湘劍雨"},{"_id":"5bfe106b9d212230a505d13a","createdAt":"2018-11-28T03:50:03.453Z","desc":"一個\"高階\"的安卓模板工程。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8boymtj307i0f0jst","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8bughtj307i0f00st","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8bz8laj307i0f0mxd","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8c3m82j307i0f0jrf","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8crc2jg30900i0hbu"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/getActivity/AndroidProject","used":true,"who":"lijinshanmx"},{"_id":"5bfe11359d2122308e7445bb","createdAt":"2018-11-28T03:53:25.547Z","desc":"Simplegraph是用於簡單圖形檢視的android庫,類似於您在硬幣交換站點上看到的。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno8db6uwj305k0b4q55"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/franticnick/simplegraph","used":true,"who":"lijinshanmx"},{"_id":"5bfe11669d212230a505d13c","createdAt":"2018-11-28T03:54:14.634Z","desc":"用於模糊檢視背景的庫。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno9fgnepg30m80gokjn"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/danielzeller/Blur-LIB-Android","used":true,"who":"lijinshanmx"},{"_id":"5bfe11fc9d2122309ed76716","createdAt":"2018-11-28T03:56:44.414Z","desc":"使用lua語言了開發android應用。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno9mmdcjg30bs0kq47e","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno9tikx7g30bs0kqmzx","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno9tpjd9g30bs0kqgm8"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/hanks-zyh/luaDevAndroid","used":true,"who":"lijinshanmx"},{"_id":"5bfe12d19d2122309624cbae","createdAt":"2018-11-28T04:00:17.782Z","desc":"適用於AndroidX的ShimmerRecyclerView。","images":["https://ww1.sinaimg.cn/large/0073sXn7gy1fxnobmepu2g30go0tnncm","https://ww1.sinaimg.cn/large/0073sXn7gy1fxnobn19fig30bo0kr7d0","https://ww1.sinaimg.cn/large/0073sXn7gy1fxnobnuw4wg30go0tnx47"],"publishedAt":"2018-11-28T00:00:00.0Z","source":"chrome","type":"Android","url":"https://github.com/mike14u/shimmer-recyclerview-x","used":true,"who":"lijinshanmx"}]
     */

    private boolean error;
    private List<ResultsBean> results;

    public boolean isError() {
        return error;
    }

    public void setError(boolean error) {
        this.error = error;
    }

    public List<ResultsBean> getResults() {
        return results;
    }

    public void setResults(List<ResultsBean> results) {
        this.results = results;
    }

    public static class ResultsBean {
        /**
         * _id : 5be404e49d21223dd88989d3
         * createdAt : 2018-11-08T09:41:56.840Z
         * desc : 微博,微信相簿效果,微信視訊拖放效果
         * images : ["https://ww1.sinaimg.cn/large/0073sXn7gy1fxno5tb0h2g308w0g01l3","https://ww1.sinaimg.cn/large/0073sXn7gy1fxno5xiiyrg308w0g0npi"]
         * publishedAt : 2018-11-28T00:00:00.0Z
         * source : web
         * type : Android
         * url : https://github.com/moyokoo/Diooto
         * used : true
         * who : miaoyj
         */

        private String _id;
        private String createdAt;
        private String desc;
        private String publishedAt;
        private String source;
        private String type;
        private String url;
        private boolean used;
        private String who;
        private List<String> images;

        public String get_id() {
            return _id;
        }

        public void set_id(String _id) {
            this._id = _id;
        }

        public String getCreatedAt() {
            return createdAt;
        }

        public void setCreatedAt(String createdAt) {
            this.createdAt = createdAt;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }

        public String getPublishedAt() {
            return publishedAt;
        }

        public void setPublishedAt(String publishedAt) {
            this.publishedAt = publishedAt;
        }

        public String getSource() {
            return source;
        }

        public void setSource(String source) {
            this.source = source;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public boolean isUsed() {
            return used;
        }

        public void setUsed(boolean used) {
            this.used = used;
        }

        public String getWho() {
            return who;
        }

        public void setWho(String who) {
            this.who = who;
        }

        public List<String> getImages() {
            return images;
        }

        public void setImages(List<String> images) {
            this.images = images;
        }
    }
}

例子一Trofit介面

import io.reactivex.Observable;
import retrofit2.http.GET;
import retrofit2.http.Path;

public interface GetRequest_Interface {
    @GET("ajax.php?a=fy&f=auto&t=auto&w=hi%20world")
    Observable<Translation> getCall();
    // 註解裡傳入 網路請求 的部分URL地址
    // Retrofit把網路請求的URL分成了兩部分:一部分放在Retrofit物件裡,另一部分放在網路請求接口裡
    // 如果接口裡的url是一個完整的網址,那麼放在Retrofit物件裡的URL可以忽略
    // 採用Observable<...>介面
    // getCall()是接受網路請求資料的方法

    @GET("api/data/Android/20/{page}")
    Observable<GankBean> getAndroidInfo(@Path("page") int page);

}
 

例子二實體類

import android.util.Log;

public class Translation {

    /**
     * status : 1
     * content : {"from":"en-EU","to":"zh-CN","out":"示例","vendor":"ciba","err_no":0}
     */

    private int status;
    private ContentBean content;

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public ContentBean getContent() {
        return content;
    }

    public void setContent(ContentBean content) {
        this.content = content;
    }

    public static class ContentBean {
        /**
         * from : en-EU
         * to : zh-CN
         * out : 示例
         * vendor : ciba
         * err_no : 0
         */

        private String from;
        private String to;
        private String out;
        private String vendor;
        private int err_no;

        public String getFrom() {
            return from;
        }

        public void setFrom(String from) {
            this.from = from;
        }

        public String getTo() {
            return to;
        }

        public void setTo(String to) {
            this.to = to;
        }

        public String getOut() {
            return out;
        }

        public void setOut(String out) {
            this.out = out;
        }

        public String getVendor() {
            return vendor;
        }

        public void setVendor(String vendor) {
            this.vendor = vendor;
        }

        public int getErr_no() {
            return err_no;
        }

        public void setErr_no(int err_no) {
            this.err_no = err_no;
        }
    }
    //定義 輸出返回資料 的方法
    public void show() {
        Log.d("RxJava", content.out );
    }
}

例子二介面

import io.reactivex.Observable;
import retrofit2.Call;
import retrofit2.http.GET;

public interface GnakApi {
    @GET("api/data/Android/10/1")
    Call<GankBean> getAndroidInfo();

    @GET("api/data/Android/10/1")
    Observable<GankBean> getAndroidInfo2();
}
 

在MainActivity中如何使用:

簡單請求

 case R.id.mainBtn3:
                Retrofit retrofit1 = new Retrofit.Builder()
                        .baseUrl("http://gank.io/")
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
                Call<GankBean> call = retrofit1.create(GnakApi.class).getAndroidInfo();
                call.enqueue(new Callback<GankBean>() {
                    @Override
                    public void onResponse(Call<GankBean> call, Response<GankBean> response) {
                        GankBean.ResultsBean bean = response.body().getResults().get(1);
                        getDataTv.setText(
                                "_id:" + bean.get_id() + "\n"
                                        + "createdAt:" + bean.getCreatedAt() + "\n"
                                        + "desc:" + bean.getDesc() + "\n"
                                        + "images:" + bean.getImages() + "\n"
                                        + "publishedAt:" + bean.getPublishedAt() + "\n"
                                        + "source" + bean.getSource() + "\n"
                                        + "type:" + bean.getType() + "\n"
                                        + "url: " + bean.getUrl() + "\n"
                                        + "who:" + bean.getWho());
                    }
                    @Override
                    public void onFailure(Call<GankBean> call, Throwable t) {

                    }
                });
                break;

配合RxJava使用

case R.id.mainBtn4:
                Retrofit retrofit2 = new Retrofit.Builder()
                        .baseUrl("http://gank.io/")
                        .addConverterFactory(GsonConverterFactory.create())
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支援RxJava
                        .build();
                Observable<GankBean> observable2 = retrofit2.create(GnakApi.class).getAndroidInfo2();
                // 3. 傳送網路請求(非同步)
                observable2.subscribeOn(Schedulers.io())               // 在IO執行緒進行網路請求
                        .observeOn(AndroidSchedulers.mainThread())  // 回到主執行緒 處理請求結果
                        .subscribe(new Observer<GankBean>() {

                            // 傳送請求後呼叫該複寫方法(無論請求成功與否)
                            @Override
                            public void onSubscribe(Disposable d) {
                        // 初始化工作
                            }

                            // 傳送請求成功後呼叫該複寫方法
                            @Override
                            public void onNext(GankBean result) {
                        // 對返回結果Translation類物件 進行處理
                                GankBean.ResultsBean bean = result.getResults().get(1);
                                getDataTv.setText(
                                        "_id:" + bean.get_id() + "\n"
                                                + "createdAt:" + bean.getCreatedAt() + "\n"
                                                + "desc:" + bean.getDesc() + "\n"
                                                + "images:" + bean.getImages() + "\n"
                                                + "publishedAt:" + bean.getPublishedAt() + "\n"
                                                + "source" + bean.getSource() + "\n"
                                                + "type:" + bean.getType() + "\n"
                                                + "url: " + bean.getUrl() + "\n"
                                                + "who:" + bean.getWho());
                            }

                            // 傳送請求成功後,先呼叫onNext()再呼叫該複寫方法
                            @Override
                            public void onComplete() {

                            }
                            // 傳送請求失敗後呼叫該複寫方法
                            @Override
                            public void onError(Throwable e) {

                            }

                        });

                break;

輪詢請求

case R.id.mainBtn5:
                // 步驟1:建立Retrofit物件
                Retrofit retrofit = new Retrofit.Builder()
                        .baseUrl("http://fy.iciba.com/") // 設定 網路請求 Url
                        .addConverterFactory(GsonConverterFactory.create()) //設定使用Gson解析(記得加入依賴)
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支援RxJava
                        .build();

                // 步驟2:建立 網路請求介面 的例項
                GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);

                // 步驟3:採用Observable<...>形式 對 網路請求 進行封裝
                Observable<Translation> observable = request.getCall();

                // 步驟4:傳送網路請求 & 通過repeatWhen()進行輪詢
                observable.repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
                    @Override
                    // 在Function函式中,必須對輸入的 Observable<Object>進行處理,此處使用flatMap操作符接收上游的資料
                    public ObservableSource<?> apply(@NonNull Observable<Object> objectObservable) throws Exception {
                        // 將原始 Observable 停止傳送事件的標識(Complete() /  Error())轉換成1個 Object 型別資料傳遞給1個新被觀察者(Observable)
                        // 以此決定是否重新訂閱 & 傳送原來的 Observable,即輪詢
                        // 此處有2種情況:
                        // 1. 若返回1個Complete() /  Error()事件,則不重新訂閱 & 傳送原來的 Observable,即輪詢結束
                        // 2. 若返回其餘事件,則重新訂閱 & 傳送原來的 Observable,即繼續輪詢
                        return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Object throwable) throws Exception {

                                // 加入判斷條件:當輪詢次數 = 30次後,就停止輪詢
                                if (i > 30) {
                                    // 此處選擇傳送onError事件以結束輪詢,因為可觸發下游觀察者的onError()方法回撥
                                    return Observable.error(new Throwable("輪詢結束"));
                                }
                                // 若輪詢次數<4次,則傳送1Next事件以繼續輪詢
                                // 注:此處加入了delay操作符,作用 = 延遲一段時間傳送(此處設定 = 2s),以實現輪詢間間隔設定
                                return Observable.just(1).delay(2000, TimeUnit.MILLISECONDS);
                            }
                        });

                    }
                }).subscribeOn(Schedulers.io())               // 切換到IO執行緒進行網路請求
                        .observeOn(AndroidSchedulers.mainThread())  // 切換回到主執行緒 處理請求結果
                        .subscribe(new Observer<Translation>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                            }

                            @Override
                            public void onNext(Translation result) {
                                // e.接收伺服器返回的資料
                                result.show() ;
                                getDataTv.setText(result.getContent().getOut());
                                i++;
                            }

                            @Override
                            public void onError(Throwable e) {
                                // 獲取輪詢結束資訊

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


                break;

輪詢請求2

 case R.id.mainBtn7:
                // 步驟1:建立Retrofit物件
                Retrofit retrofit4 = new Retrofit.Builder()
                        .baseUrl("http://gank.io/") // 設定 網路請求 Url
                        .addConverterFactory(GsonConverterFactory.create()) //設定使用Gson解析(記得加入依賴)
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支援RxJava
                        .build();

                // 步驟2:建立 網路請求介面 的例項
                GetRequest_Interface request4 = retrofit4.create(GetRequest_Interface.class);

                // 步驟3:採用Observable<...>形式 對 網路請求 進行封裝
                Observable<GankBean> observable4 = request4.getAndroidInfo(0);

                // 步驟4:傳送網路請求 & 通過repeatWhen()進行輪詢
                observable4.repeatWhen(new Function<Observable<Object>, ObservableSource<?>>() {
                    @Override
                    // 在Function函式中,必須對輸入的 Observable<Object>進行處理,此處使用flatMap操作符接收上游的資料
                    public ObservableSource<?> apply(@NonNull Observable<Object> objectObservable) throws Exception {
                        // 將原始 Observable 停止傳送事件的標識(Complete() /  Error())轉換成1個 Object 型別資料傳遞給1個新被觀察者(Observable)
                        // 以此決定是否重新訂閱 & 傳送原來的 Observable,即輪詢
                        // 此處有2種情況:
                        // 1. 若返回1個Complete() /  Error()事件,則不重新訂閱 & 傳送原來的 Observable,即輪詢結束
                        // 2. 若返回其餘事件,則重新訂閱 & 傳送原來的 Observable,即繼續輪詢
                        return objectObservable.flatMap(new Function<Object, ObservableSource<?>>() {
                            @Override
                            public ObservableSource<?> apply(@NonNull Object throwable) throws Exception {

                                // 加入判斷條件:當輪詢次數 = 10次後,就停止輪詢
                                if (i > 10) {
                                    // 此處選擇傳送onError事件以結束輪詢,因為可觸發下游觀察者的onError()方法回撥
                                    return Observable.error(new Throwable("輪詢結束"));
                                }
                                // 若輪詢次數<4次,則傳送1Next事件以繼續輪詢
                                // 注:此處加入了delay操作符,作用 = 延遲一段時間傳送(此處設定 = 2s),以實現輪詢間間隔設定
                                return Observable.just(1).delay(1000, TimeUnit.MILLISECONDS);
                            }
                        });

                    }
                }).subscribeOn(Schedulers.io())               // 切換到IO執行緒進行網路請求
                        .observeOn(AndroidSchedulers.mainThread())  // 切換回到主執行緒 處理請求結果
                        .subscribe(new Observer<GankBean>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                            }

                            @Override
                            public void onNext(GankBean result) {
                                // e.接收伺服器返回的資料

                                getDataTv.setText(result.getResults().get(i).getDesc());
                                i++;
                            }

                            @Override
                            public void onError(Throwable e) {
                                // 獲取輪詢結束資訊

                            }

                            @Override
                            public void onComplete() {

                            }
                        });


                break;