轉載請註明出處: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()); } } }