转载请注明出处:http://www.wangxinarhat.com/2016/04/16/2016-04-16-gee-weather/java
最近学习了Rxjava、Retrofit,作一个小项目实践下,使用了和风天气API,代码已上传至githubgit
RxJavagithub
Retrofit数据库
GreenDaoapi
Glide安全
EventBus网络
高德定位app
由于和风天气提供的接口须要地理位置的编号做为参数,可是高德定位返回的结果并无地理位置编号ide
因此须要本地数据库存储全部的地理位置编号,利用高德定位的位置查询出编号
项目选择GreenDao简化开发流程post
在 .src/main 目录下新建一个与 java 同层级的「java-gen」目录,用于存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等类。
配置 Android 工程(app)的 build.gradle,添加 sourceSets,dependencies就不用说了
sourceSets { main { java.srcDirs = ['src/main/java', 'src/main/java-gen'] } }
新建「greenDAO Generator」模块 (Java 工程)
经过 File -> New -> New Module -> Java Library -> 填写相应的包名与类名 -> Finish
生成 DAO 文件(数据库)
执行 generator 工程,你将会在控制台看到以下日志,而且在主工程「java-gen」下会发现生成了DaoMaster、DaoSession、NoteDao、Note共4个类文件
使用GreenDao的查询功能
初始化
private void setupDatabase() { // 经过 DaoMaster 的内部类 DevOpenHelper,能够获得一个便利的 SQLiteOpenHelper 对象。 // 可能你已经注意到了,你并不须要去编写「CREATE TABLE」这样的 SQL 语句,由于 greenDAO 已经帮你作了。 // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除全部的表,意味着这将致使数据的丢失。 // 因此,在正式的项目中,你还应该作一层封装,来实现数据库的安全升级。 helper = new DaoMaster.DevOpenHelper(this, Constants.DB_NAME, null); db = helper.getWritableDatabase(); // 注意:该数据库链接属于 DaoMaster,因此多个 Session 指的是相同的数据库链接。 daoMaster = new DaoMaster(db); daoSession = daoMaster.newSession(); }
获取DAO
private CITYDao getCityInfoDao() { // 经过 BaseApplication 类提供的 getDaoSession() 获取具体 Dao return daoSession.getCITYDao(); }
经过高德定位获取的信息查询数据库
private CITY search(String city_province, String city_town, String city_area) { if (city_province != null) { city_province = city_province.replace("市", "") .replace("省", "") .replace("自治区", "") .replace("特别行政区", "") .replace("地区", "") .replace("区", "") .replace("盟", ""); } if (city_town != null) { city_town = city_town.replace("市", "") .replace("省", "") .replace("自治区", "") .replace("特别行政区", "") .replace("地区", "") .replace("区", "") .replace("盟", ""); } if (city_area != null) { city_area = city_area.replace("市", "") .replace("省", "") .replace("自治区", "") .replace("特别行政区", "") .replace("地区", "") .replace("区", "") .replace("盟", ""); } //在 QueryBuilder 类中内置两个 Flag 用于方便输出执行的 SQL 语句与传递参数的值 QueryBuilder.LOG_SQL = true; QueryBuilder.LOG_VALUES = true; return getCityInfoDao().queryBuilder().where(CITYDao.Properties.City_town.eq(city_town)).unique(); }
接口
public interface WeatherApi { @GET("weather") rx.Observable<WeatherInfo> queryWeather(@Query("city") String city, @Query("key") String key); @GET("http://api.fir.im/apps/latest/和风天气key") rx.Observable<VersionAPI> mVersionAPI( @Query("api_token") String api_token); }
数据转换
public class WeatherInfo2Weather implements Func1<WeatherInfo,Weather> { public static WeatherInfo2Weather newInstance(){ return new WeatherInfo2Weather(); } @Override public Weather call(WeatherInfo weatherInfo) { return weatherInfo.mHeWeatherDataService30.get(0); } }
网络请求
private Observer<? super Weather> getObserver() { if (null == observer) { observer = new Observer<Weather>() { @Override public void onCompleted() { mFlyLayout.onRefreshFinish(); if (SomeUtils.isNetworkConnected(MainActivity.this)) { Snackbar.make(mRecyclerview, "加载完毕,(*^▽^*)", Snackbar.LENGTH_SHORT).show(); } else { Snackbar.make(mRecyclerview, "网络异常,(ಥ _ ಥ)", Snackbar.LENGTH_SHORT).show(); } isLoading = false; } @Override public void onError(Throwable e) { mFlyLayout.onRefreshFinish(); Snackbar.make(mRecyclerview, "网络异常,(ಥ _ ಥ)", Snackbar.LENGTH_SHORT).show(); LogUtils.LOGE(TAG, e.getMessage()); isLoading = false; } @Override public void onNext(Weather weather) { if (null == mAdapter) { mAdapter = new WeatherAdapter(); } mRecyclerview.setAdapter(mAdapter); mAdapter.setData(weather); } }; } return observer; }
定位位置改变后查询位置编码,发送事件,从新请求网络
@Override public void onLocationChanged(AMapLocation aMapLocation) { if (aMapLocation != null) { if (aMapLocation.getErrorCode() == 0) { //定位成功回调信息,设置相关消息 if (StringUtils.hasMeaningful(aMapLocation.getDistrict())) { SPUtils.setCityInfo(aMapLocation.getCity(), aMapLocation.getDistrict()); if (!StringUtils.hasMeaningful(SPUtils.getDistrict())) { search(aMapLocation.getProvince(), aMapLocation.getCity(), aMapLocation.getDistrict()); EventBus.getDefault().post(new MessageEvent()); } } } else { //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。 Log.e("AmapError", "location Error, ErrCode:" + aMapLocation.getErrorCode() + ", errInfo:" + aMapLocation.getErrorInfo()); } } }