retrofit+RxJava+okhttp簡便封裝實現網絡請求(詳解)

寫在開頭

在開發中,掉接口請求數據時再平常不過的事情了,如何讓這個過程更簡單更適合自己感覺很重要。最近項目對此進行了一下簡單的封裝,用着挺好。提供給大家共同學習,也希望提出意見,共同進步。

自定義Interceptor攔截器工具類

本工具類用於打印okhttp的響應,輔助開發
    public class NetConfig implements Interceptor {

        private static NetConfig instance;
        private OkHttpClient client;
        private Gson gson;

        //單例的方式創建本類對象
        public static NetConfig getInstance() {
            if (instance == null) {
                synchronized (NetConfig.class) {
                    instance = new NetConfig();
                }
            }
            return instance;
        }

        //創建OkHttpClient對象,並指定讀取,寫入,連接超時時間,添加okhttp攔截器
        public OkHttpClient getClient() {
            if (client == null)
                client = new OkHttpClient.Builder()
                        .readTimeout(30, TimeUnit.SECONDS)
                        .writeTimeout(30, TimeUnit.SECONDS)
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .addInterceptor(this)
                        .build();
            return client;
        }

        public Gson getGson() {
            if (gson == null)
                gson = new GsonBuilder()
                        .enableComplexMapKeySerialization() //支持Map的key爲複雜對象的形式
                        .create();
            return gson;
        }

        //打印請求和響應的基本信息,輔助開發
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            long t1 = System.nanoTime();
            Request.Builder builder = request.newBuilder();

            Response response = chain.proceed(builder
                    .build());

            Log.e("tag", "request:" + request.toString());
            long t2 = System.nanoTime();
            okhttp3.MediaType mediaType = response.body().contentType();
            Log.e("tag", mediaType.toString());
            if ("application/json; charset=utf-8".equals(mediaType.toString())) {
                Log.e("tag", String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
                        response.request().url(), (t2 - t1) / 1e6d, response.headers()));
                String content = response.body().string();
                Log.e("tag", "response body:" + content);
                return response.newBuilder()
                        .body(okhttp3.ResponseBody.create(mediaType, content))
                        .build();
            }
            return response;
        }

編寫retrofit工具類

    public class RetorfitUtil {

        private static RetorfitUtil instance;
        private Retrofit retrofit;
        private Gson gson;

        private RetorfitUtil() {

            retrofit = new Retrofit.Builder()
                    //配置主機地址,baseUrl必須以斜槓結尾
                    .baseUrl(ApiUrls.BaseUrl)
                    //設置自己定義的okhttpclient
                    .client(new NetConfig().getClient())
                    //解析json的工具
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    //支持RxJava
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
        }

        /**
         * 靜態內部類
         */
        public static RetorfitUtil getInstance() {
            if (instance == null) {
                synchronized (RetorfitUtil.class) {
                    instance = new RetorfitUtil();
                }
            }
            return instance;
        }

        /**
         * 得到ResponseInfoAPI的對象
         *
         * @return
         */
        public ResponseInfoAPI create() {
            return retrofit.create(ResponseInfoAPI.class);
        }
    }

創建類編寫url和創建一個retrofit接口(這一部分根據項目自己發揮就好)

    public class ApiUrls {

    //主機地址(以斜槓結尾  注意注意注意注意注意注意注意)
    public static final String BaseUrl = "http://192.168.2.202:8080/";

    //登錄
    public static final String login = "user/login";

    }
    //retrofit註解請移步 http://blog.csdn.net/qiang_xi/article/details/53959437
    public interface ResponseInfoAPI {

        //登錄
        @POST(ApiUrls.login)
        @FormUrlEncoded
        Observable<TopResponse<LoginInfo>> getLoginData(@Field("username") String username, @Field("password") String password);

    }

封裝使用

    //得到retrofit對象併發起網絡請求
    RetorfitUtil.getInstance().create().getLoginData(username, pwd)
        //指定調度器  用於IO密集型任務,異步阻塞IO操作,這個調度器的線程池會根據需要增長(常用)
       .subscribeOn(Schedulers.io())
        //此調度器爲RxAndroid特有,指定數據接收發生在UI線程
       .observeOn(AndroidSchedulers.mainThread())
       //類型轉換   在onNext中變成你想要的類型 FlatMap可以改變原始Observable變成另外一個Observable
       .flatMap(new Func1<TopResponse<LoginInfo>, Observable<LoginInfo>>() {
           @Override
           public Observable<LoginInfo> call(TopResponse<LoginInfo> loginInfoTopResponse) {

           }
       })
       .subscribe(new Subscriber<LoginInfo>() {
           @Override
           public void onCompleted() {
        //這裏開發中基本不用
           }

           @Override
           public void onError(Throwable e) {
              //失敗的回到
           }

           @Override
           public void onNext(LoginInfo loginInfo) {
               //成功的回調,在這裏就是你flat中想要的數據
           }
       });

        //RXJava還沒詳細總結,更多請移步http://blog.csdn.net/xx326664162/article /details/52068014 個人感覺挺好

寫在後面

這是個人的一個在使用中的一個簡單的總結,供大家參考。當然你有什麼意見也挺發出來,一起討論,共同進步。
發佈了39 篇原創文章 · 獲贊 33 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章