来用一下Retrofit+RxJava,用了一个天气的接口来试验
请求的地址:https://www.sojson.com/open/api/weather/json.shtml?city=长春
1、添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.1.0' implementation 'com.squareup.retrofit2:converter-gson:2.1.0' implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0' implementation 'io.reactivex:rxandroid:1.2.1' implementation 'io.reactivex:rxjava:1.2.1'
2、添加网络请求权限
<uses-permission android:name="android.permission.INTERNET"/>
3、创建接受服务器返回的数据的类Weather,用来解析Json
Json格式如下:
{"date":"20180525","message":"Success !","status":200,"city":"北京","count":623,"data":{"shidu":"48%","pm25":55.0,"pm10":129.0,"quality":"轻度污染","wendu":"23","ganmao":"儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼","yesterday":{"date":"24日星期四","sunrise":"04:53","high":"高温 31.0℃","low":"低温 17.0℃","sunset":"19:30","aqi":114.0,"fx":"南风","fl":"3-4级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},"forecast":[{"date":"25日星期五","sunrise":"04:53","high":"高温 31.0℃","low":"低温 19.0℃","sunset":"19:30","aqi":94.0,"fx":"西南风","fl":"<3级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"},{"date":"26日星期六","sunrise":"04:52","high":"高温 30.0℃","low":"低温 16.0℃","sunset":"19:31","aqi":72.0,"fx":"西北风","fl":"4-5级","type":"雷阵雨","notice":"带好雨具,别在树下躲雨"},{"date":"27日星期日","sunrise":"04:51","high":"高温 31.0℃","low":"低温 15.0℃","sunset":"19:32","aqi":77.0,"fx":"西南风","fl":"<3级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"},{"date":"28日星期一","sunrise":"04:51","high":"高温 30.0℃","low":"低温 18.0℃","sunset":"19:33","aqi":51.0,"fx":"北风","fl":"<3级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"},{"date":"29日星期二","sunrise":"04:50","high":"高温 29.0℃","low":"低温 16.0℃","sunset":"19:34","aqi":50.0,"fx":"北风","fl":"<3级","type":"晴","notice":"愿你拥有比阳光明媚的心情"}]}}
利用GsonFormat创建Weather
package com.example.administrator.retrofitrxjavatest; import java.util.List; public class Weather { /** * date : 20180523 * message : Success ! * status : 200 * city : 北京 * count : 1011 * data : {"shidu":"24%","pm25":73,"pm10":356,"quality":"重度污染","wendu":"16","ganmao":"老年人及心脏、呼吸系统疾病患者人群应停留在室内,停止户外运动,一般人群减少户外运动","yesterday":{"date":"22日星期二","sunrise":"04:55","high":"高温 25.0℃","low":"低温 10.0℃","sunset":"19:28","aqi":98,"fx":"西北风","fl":"4-5级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},"forecast":[{"date":"23日星期三","sunrise":"04:54","high":"高温 29.0℃","low":"低温 15.0℃","sunset":"19:29","aqi":77,"fx":"西南风","fl":"3-4级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},{"date":"24日星期四","sunrise":"04:53","high":"高温 31.0℃","low":"低温 17.0℃","sunset":"19:30","aqi":96,"fx":"南风","fl":"<3级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},{"date":"25日星期五","sunrise":"04:53","high":"高温 30.0℃","low":"低温 19.0℃","sunset":"19:30","aqi":90,"fx":"南风","fl":"<3级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},{"date":"26日星期六","sunrise":"04:52","high":"高温 28.0℃","low":"低温 14.0℃","sunset":"19:31","aqi":71,"fx":"南风","fl":"<3级","type":"阴","notice":"不要被阴云遮挡住好心情"},{"date":"27日星期日","sunrise":"04:51","high":"高温 28.0℃","low":"低温 16.0℃","sunset":"19:32","aqi":77,"fx":"西北风","fl":"3-4级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"}]} */ public String date; public String message; public int status; public String city; public int count; public DataBean data; public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public DataBean getData() { return data; } public void setData(DataBean data) { this.data = data; } public static class DataBean { /** * shidu : 24% * pm25 : 73.0 * pm10 : 356.0 * quality : 重度污染 * wendu : 16 * ganmao : 老年人及心脏、呼吸系统疾病患者人群应停留在室内,停止户外运动,一般人群减少户外运动 * yesterday : {"date":"22日星期二","sunrise":"04:55","high":"高温 25.0℃","low":"低温 10.0℃","sunset":"19:28","aqi":98,"fx":"西北风","fl":"4-5级","type":"晴","notice":"愿你拥有比阳光明媚的心情"} * forecast : [{"date":"23日星期三","sunrise":"04:54","high":"高温 29.0℃","low":"低温 15.0℃","sunset":"19:29","aqi":77,"fx":"西南风","fl":"3-4级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},{"date":"24日星期四","sunrise":"04:53","high":"高温 31.0℃","low":"低温 17.0℃","sunset":"19:30","aqi":96,"fx":"南风","fl":"<3级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},{"date":"25日星期五","sunrise":"04:53","high":"高温 30.0℃","low":"低温 19.0℃","sunset":"19:30","aqi":90,"fx":"南风","fl":"<3级","type":"晴","notice":"愿你拥有比阳光明媚的心情"},{"date":"26日星期六","sunrise":"04:52","high":"高温 28.0℃","low":"低温 14.0℃","sunset":"19:31","aqi":71,"fx":"南风","fl":"<3级","type":"阴","notice":"不要被阴云遮挡住好心情"},{"date":"27日星期日","sunrise":"04:51","high":"高温 28.0℃","low":"低温 16.0℃","sunset":"19:32","aqi":77,"fx":"西北风","fl":"3-4级","type":"多云","notice":"阴晴之间,谨防紫外线侵扰"}] */ public String shidu; public double pm25; public double pm10; public String quality; public String wendu; public String ganmao; public YesterdayBean yesterday; public List<ForecastBean> forecast; public String getShidu() { return shidu; } public void setShidu(String shidu) { this.shidu = shidu; } public double getPm25() { return pm25; } public void setPm25(double pm25) { this.pm25 = pm25; } public double getPm10() { return pm10; } public void setPm10(double pm10) { this.pm10 = pm10; } public String getQuality() { return quality; } public void setQuality(String quality) { this.quality = quality; } public String getWendu() { return wendu; } public void setWendu(String wendu) { this.wendu = wendu; } public String getGanmao() { return ganmao; } public void setGanmao(String ganmao) { this.ganmao = ganmao; } public YesterdayBean getYesterday() { return yesterday; } public void setYesterday(YesterdayBean yesterday) { this.yesterday = yesterday; } public List<ForecastBean> getForecast() { return forecast; } public void setForecast(List<ForecastBean> forecast) { this.forecast = forecast; } public static class YesterdayBean { /** * date : 22日星期二 * sunrise : 04:55 * high : 高温 25.0℃ * low : 低温 10.0℃ * sunset : 19:28 * aqi : 98.0 * fx : 西北风 * fl : 4-5级 * type : 晴 * notice : 愿你拥有比阳光明媚的心情 */ public String date; public String sunrise; public String high; public String low; public String sunset; public double aqi; public String fx; public String fl; public String type; public String notice; public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getSunrise() { return sunrise; } public void setSunrise(String sunrise) { this.sunrise = sunrise; } public String getHigh() { return high; } public void setHigh(String high) { this.high = high; } public String getLow() { return low; } public void setLow(String low) { this.low = low; } public String getSunset() { return sunset; } public void setSunset(String sunset) { this.sunset = sunset; } public double getAqi() { return aqi; } public void setAqi(double aqi) { this.aqi = aqi; } public String getFx() { return fx; } public void setFx(String fx) { this.fx = fx; } 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 String getNotice() { return notice; } public void setNotice(String notice) { this.notice = notice; } } public static class ForecastBean { /** * date : 23日星期三 * sunrise : 04:54 * high : 高温 29.0℃ * low : 低温 15.0℃ * sunset : 19:29 * aqi : 77.0 * fx : 西南风 * fl : 3-4级 * type : 晴 * notice : 愿你拥有比阳光明媚的心情 */ public String date; public String sunrise; public String high; public String low; public String sunset; public String aqi; public String fx; public String fl; public String type; public String notice; public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getSunrise() { return sunrise; } public void setSunrise(String sunrise) { this.sunrise = sunrise; } public String getHigh() { return high; } public void setHigh(String high) { this.high = high; } public String getLow() { return low; } public void setLow(String low) { this.low = low; } public String getSunset() { return sunset; } public void setSunset(String sunset) { this.sunset = sunset; } public String getAqi() { return aqi; } public void setAqi(String aqi) { this.aqi = aqi; } public String getFx() { return fx; } public void setFx(String fx) { this.fx = fx; } 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 String getNotice() { return notice; } public void setNotice(String notice) { this.notice = notice; } } } }
4、创建用于请求网络的接口RxWeatherService
interface RxWeatherService { @GET("weather/json.shtml") Observable<Weather> getCall(@Query("city") String city); }
5、给Retrofit做一下封装,采用单例,新建Retrofit的实例,然后使用Gson解析,支持RxJava,
这些操作都封装好了,返回一个网络请求接口实例,我们在Maintivity调用就好了
public class RequestUtils { private static final String baseUrl = "https://www.sojson.com/open/api/"; private static Retrofit retrofit; private static RxWeatherService rxWeatherService; public static RxWeatherService getInstance() { /** * 创建Retrofit对象,设置网络请求url,添加Gson依赖,添加Rx适配器,创建网络请求接口实例 */ if (retrofit == null) { synchronized (RequestUtils.class) { if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); rxWeatherService = retrofit.create(RxWeatherService.class); } } } return rxWeatherService; } }
6、在MainActivity中发送请求
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); sendRequestWithRxJava(); } private void sendRequestWithRxJava() { RequestUtils.getInstance().getCall(param) .subscribeOn(Schedulers.io())// 切换到IO线程进行网络请求 .observeOn(AndroidSchedulers.mainThread())// 切换回到主线程 处理请求结果 .subscribe(new Subscriber<Weather>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { Toast.makeText(MainActivity.this, "接口异常,请等待", Toast.LENGTH_SHORT).show(); } @Override public void onNext(Weather weather) { forecastList = weather.getData().getForecast(); city.setText(weather.getCity().toString()); currentTemp.setText(weather.getData().getWendu().toString() + "℃"); type.setText(forecastList.get(0).getType().toString()); aqi.setText("空气 " + weather.getData().getQuality().toString()); ganmao.setText("温馨提示:" + weather.getData().getGanmao().toString()); bodyTemp.setText("体感温度 " + weather.getData().getWendu().toString() + "℃"); shidu.setText("湿度 " + weather.getData().getShidu().toString()); fxfl.setText(forecastList.get(0).getFx().toString() + " " + forecastList.get(0).getFl().toString()); sunrise.setText("日出 " + forecastList.get(0).getSunrise().toString()); sunset.setText("日落 " + forecastList.get(0).getSunset().toString()); pm25.setText(forecastList.get(0).getAqi().toString()); aqi2.setText(weather.getData().getQuality().toString()); pm25Small.setText("PM2.5: " + forecastList.get(0).getAqi().toString()); //我们从网上得到的数据放到了forecastList中,然后把他传到适配器中显示到listview当中 adapter = new ForecastAdapter(MainActivity.this, R.layout.weather_list_item, forecastList); tomorrowWeatherLisview.setAdapter(adapter); } }); }
7、测试结果:
8、Demo地址:https://github.com/pengboboer/RetrofitRxJavaTest
MainActivity的布局文件还有几张图片在Demo当中,这里就不贴出来了,有需要的自己下载
说明:这个天气接口是免费的,在这里感谢接口站长,这只是一个小Demo,没有设置缓存,但如果大家真的在自己的项目中用到了这个接口,尤其有城市添加和城市切换功能的时候,一定要设置缓存,一方面自己的App比较流畅,再一个也减轻接口的请求压力。
总结
使用Retrofit和RxJava还是很爽的,RxJava的异步还是很强大的,代码逻辑很清晰,在此记录一下,方便同学们查阅。