天天看点

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(, TimeUnit.SECONDS)
                        .writeTimeout(, TimeUnit.SECONDS)
                        .connectTimeout(, 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) / d, 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 个人感觉挺好
           

写在后面

这是个人的一个在使用中的一个简单的总结,供大家参考。当然你有什么意见也挺发出来,一起讨论,共同进步。
           
上一篇: NUnit 断言