Rxjava & Retrofit 實踐

轉載請註明出處:http://www.wangxinarhat.com/2016/04/16/2016-04-16-gee-weather/java

最近學習了Rxjava、Retrofit,作一個小項目實踐下,使用了和風天氣API,代碼已上傳至githubgit

效果

圖片描述

實現技術

  • RxJavagithub

  • Retrofit數據庫

  • GreenDaoapi

  • Glide安全

  • EventBus網絡

  • 高德定位app

GreenDao使用

由於和風天氣提供的接口須要地理位置的編號做爲參數,可是高德定位返回的結果並無地理位置編號ide

因此須要本地數據庫存儲全部的地理位置編號,利用高德定位的位置查詢出編號
項目選擇GreenDao簡化開發流程post

  1. 在 .src/main 目錄下新建一個與 java 同層級的「java-gen」目錄,用於存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等類。

  2. 配置 Android 工程(app)的 build.gradle,添加 sourceSets,dependencies就不用說了

    sourceSets {
            main {
                java.srcDirs = ['src/main/java', 'src/main/java-gen']
            }
        }
  3. 新建「greenDAO Generator」模塊 (Java 工程)
    經過 File -> New -> New Module -> Java Library -> 填寫相應的包名與類名 -> Finish

  4. 生成 DAO 文件(數據庫)
    執行 generator 工程,你將會在控制檯看到以下日誌,而且在主工程「java-gen」下會發現生成了DaoMaster、DaoSession、NoteDao、Note共4個類文件

  5. 使用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();
      }

Retrofit & Gson & RxJava實現網絡請求,數據解析

  • 接口

    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;
        }

EventBus使用

定位位置改變後查詢位置編碼,發送事件,從新請求網絡

@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());
         }
     }
 }
相關文章
相關標籤/搜索