浅谈android应用之网络通信

1. 前言

思考再三,还是先写一篇关于网络通信的博客。说起网络通信,可能你首先会想到一系列的网络通信的协议,这里不讲这些,这里只讲开发时候会使用到的网络通信框架的一些理解:RxJava+Retrofit+OkHttp。

2. 框架设计原理

一个优秀的框架具备高性能,高解耦合,通常会结合各种设计模式,以及MVP的架构来进行封装,其中网络框架的设计还需要结合这三个开源库:RxJava,Retrofit,OkHttp。

其中可能最被熟悉的开源库就是OkHttp了,但随着发展,Square公司又开发了一个新的网络请求框架,那就是Retrofit。Retrofit是基于OkHttp的,它底层的所有请求默认走的都是OkHttp。它在OkHttp的基础上进一步封装,使用注解方式让我们使用简单方便且看代码一目了然。Retrofit是基于APP发起请求的封装,也就是面向的是应用层(比如响应数据的处理和错误处理等)。而OkHttp是对底层网络请求的封装与优化(socket优化,数据压缩,buffer缓存等)。

如果说Retrofit是OkHttp的进化版,更加解耦,更加简单的话,那RxJava又有什么作用呢?

可能大家在android中都会接触到异步两种常用方式:AsyncTask 和Handler ,RxJava的作用也跟这两者相同,也是一种异步方式。但RxJava的话会更加简洁,在越复杂的场景下使用,越会感觉到RxJava的简。

所以我们这个网络框架使用到的三个开源库的分别作用是:
RxJava:提供一种简洁的异步方式
Retrofit:以注解方式发起请求,本质也是基于OkHttp发起网络请求的
OkHttp:对底层网络请求的封装与优化

3. 实例开发第一步

直接上手,一个字,干!

第一步其实很简单,就是在build.gradle项目文件中添加引入各种库配置:

    /** rxjava **/
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'io.reactivex:rxjava:1.1.0'

    /** retrofit **/
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

    /**  okhttp  **/
    compile 'com.squareup.okhttp3:okhttp:3.3.1'
    compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'

4. 实例开发第二步

第二步很简单,但千万不要忘了,需要这AndroidManifest.xml文件中声明权限:

扫描二维码关注公众号,回复: 9682764 查看本文章
<uses-permission android:name="android.permission.INTERNET" />

5. 实例开发第三步

直接上核心代码:

 private void doRequestByRxRetrofit() {
        initOkHttpClient();
        
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://wthrcdn.etouch.cn/")//基础URL,建议以 / 结尾
                .client(mOkHttpClient)//自定义client,可以不选,底层默认带有
                .addConverterFactory(GsonConverterFactory.create())//设置 Json 转换器,自动给你转好了json,很方便
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//RxJava 适配器
                .build();  //创建retrofit 实例
                
         //create之后自动转RxWeatherService 类型
        RxWeatherService rxJavaService = retrofit.create(RxWeatherService.class);
        
        rxJavaService.getMessage("北京")
                 //subscribe过程发生在io线程中,这里的参数可选其他
                .subscribeOn(Schedulers.io())      
                //Subscriber过程发生在UI线程中,也就是onNext这个回调最后会发生在UI线程中,所以可以做更新UI操作
                .observeOn(AndroidSchedulers.mainThread())    
                .subscribe(new Subscriber<WeatherEntity>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(WeatherEntity weatherEntity) {
                    	//获取数据,更新UI
                        showMsg.setText("response ==" + weatherEntity.getData().getGanmao());
                    }
                });
    }
    
    private void initOkHttpClient() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        if (mOkHttpClient == null) {
            synchronized (MainActivity.class) {
                if (mOkHttpClient == null) {
                    // 指定缓存路径,缓存大小100Mb
                    Cache cache = new Cache(new File(getExternalCacheDir(), "HttpCache"),
                            1024 * 1024 * 100);
                    mOkHttpClient = new OkHttpClient.Builder()
                            .cache(cache)
                            .addInterceptor(interceptor)
                            .retryOnConnectionFailure(true)
                            .connectTimeout(15, TimeUnit.SECONDS)
                            .build();
                }
            }
        }
    }
   

RxWeatherService接口代码如下:

	public interface RxWeatherService {
    	@GET("weather_mini")
   	    Observable<WeatherEntity> getMessage(@Query("city") String city);
	}

完整的请求地址是:http://wthrcdn.etouch.cn/weather_mini?city=北京

这里显然是以GET方式请求网络,参数weather_mini后面接了个“?”,这是一个查询参数,即查询key为city对应的value的值。这其实就是解析一组json数据!

以及附带的实体类代码:

public class WeatherEntity {
    private DataBean data;
    private int status;
    private String desc;

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    public int getStatus() {
        return status;
    }

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

    public String getDesc() {
        return desc;
    }

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

    public static class DataBean {
        private YesterdayBean yesterday;
        private String city;
        private String aqi;
        private String ganmao;
        private String wendu;
        private List<ForecastBean> forecast;

        public YesterdayBean getYesterday() {
            return yesterday;
        }

        public void setYesterday(YesterdayBean yesterday) {
            this.yesterday = yesterday;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getAqi() {
            return aqi;
        }

        public void setAqi(String aqi) {
            this.aqi = aqi;
        }

        public String getGanmao() {
            return ganmao;
        }

        public void setGanmao(String ganmao) {
            this.ganmao = ganmao;
        }

        public String getWendu() {
            return wendu;
        }

        public void setWendu(String wendu) {
            this.wendu = wendu;
        }

        public List<ForecastBean> getForecast() {
            return forecast;
        }

        public void setForecast(List<ForecastBean> forecast) {
            this.forecast = forecast;
        }

        public static class YesterdayBean {

            private String date;
            private String high;
            private String fx;
            private String low;
            private String fl;
            private String type;

            public String getDate() {
                return date;
            }

            public void setDate(String date) {
                this.date = date;
            }

            public String getHigh() {
                return high;
            }

            public void setHigh(String high) {
                this.high = high;
            }

            public String getFx() {
                return fx;
            }

            public void setFx(String fx) {
                this.fx = fx;
            }

            public String getLow() {
                return low;
            }

            public void setLow(String low) {
                this.low = low;
            }

            public String getFl() {
                return fl;
            }

            public void setFl(String fl) {
                this.fl = fl;
            }

            public String getType() {
                return type;
            }

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

        public static class ForecastBean {

            private String date;
            private String high;
            private String fengli;
            private String low;
            private String fengxiang;
            private String type;

            public String getDate() {
                return date;
            }

            public void setDate(String date) {
                this.date = date;
            }

            public String getHigh() {
                return high;
            }

            public void setHigh(String high) {
                this.high = high;
            }

            public String getFengli() {
                return fengli;
            }

            public void setFengli(String fengli) {
                this.fengli = fengli;
            }

            public String getLow() {
                return low;
            }

            public void setLow(String low) {
                this.low = low;
            }

            public String getFengxiang() {
                return fengxiang;
            }

            public void setFengxiang(String fengxiang) {
                this.fengxiang = fengxiang;
            }

            public String getType() {
                return type;
            }

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

通过上面的内容你就可以构建一个简单的基于RxJava+Retrofit+OkHttp的网络请求框架了,已对关键处做了注释。

但上面的代码主要是让你熟悉RxJava+Retrofit+OkHttp三者联系,实际开发中内容会更加的丰富。

6. 后记

再提一下,上面只是很简单的内容,无论RxJava,Retrofit,OkHttp哪一个开源库,都是值得研究的,里面有丰富与成熟使用的设计模式,我猜这篇文章你肯定没有看爽,时间充裕的情况下大家可以去啃一下,很有意思的,嘿嘿。

发布了70 篇原创文章 · 获赞 24 · 访问量 8269

猜你喜欢

转载自blog.csdn.net/angelsmiling/article/details/102831965
今日推荐