編寫簡易Android天氣應用的程式碼範例_Android

來源:互聯網
上載者:User

本文所要介紹的簡易天氣App主要用RxAndroid、MVP、Retrofit實現,首先來看看效果:
首頁內容:

右側欄天氣列表:

左側欄城市列表

首先看看Activity主要代碼(使用MVP模式):

//調用Presenter的方法擷取資料 mMainPresenter = new MainPresenterImpl(this); mMainPresenter.getPlaceData(); mMainPresenter.getWeatherData("成都"); //顯示首頁和右側欄天氣資料 public void setupWeatherData(WeatherResponse weatherResponse) {   if (weatherResponse == null) return;   setTitleText(DateUtils.getWeekDay(weatherResponse.date));   if (weatherResponse.results != null && weatherResponse.results.size() > 0) {     WeatherResult result = weatherResponse.results.get(0);     mTvCity.setText(getString(R.string.city, result.currentCity));     mTvPm25.setText(getString(R.string.pm25, result.pm25));      mWeatherDataAdapter.setData(result.weather_data);     mWeatherDataAdapter.notifyDataSetChanged();      mWeatherExtraAdapter.setData(result.index);     mWeatherExtraAdapter.notifyDataSetChanged();   } } //顯示左側欄城市列表 @Override public void setupPlaceData(List<Place> placeList) {   if (placeList == null) {     return;   }   mPlaceAdapter.setData(placeList);   mPlaceAdapter.notifyDataSetChanged(); } 

接下來看看如何在Presenter中應用RxJava、RxAndroid擷取資料

//擷取天氣資料 @Override public void getWeatherData(String place) {   if (TextUtils.isEmpty(place)) {     return;   }   mMainView.showProgress();   ServiceManager.getInstance().getApiService().getWeatherInfo(place, Constants.BAIDU_AK)       .subscribeOn(Schedulers.io())       .observeOn(AndroidSchedulers.mainThread())       .subscribe(new Subscriber<WeatherResponse>() {         @Override         public void onCompleted() {           Log.e(TAG, "onCompleted");           mMainView.hideProgress();         }          @Override         public void onError(Throwable e) {           Log.e(TAG, e.getMessage(), e);           mMainView.hideProgress();         }          @Override         public void onNext(WeatherResponse weatherResponse) {           mMainView.setupWeatherData(weatherResponse);         }       }); } public interface ApiService {    /*@GET("service/getIpInfo.php")   Call<GetIpInfoResponse> getIpInfo(@Query("ip") String ip);*/    @GET("service/getIpInfo.php")   Observable<GetIpInfoResponse> getIpInfo(@Query("ip") String ip);     //http://api.map.baidu.com/telematics/v3/weather?location=%E6%88%90%E9%83%BD&output=json&ak=MPDgj92wUYvRmyaUdQs1XwCf   @GET("/telematics/v3/weather?output=json")   Observable<WeatherResponse> getWeatherInfo(@Query("location") String location, @Query("ak") String ak); } 

如上所述,我們通過百度api擷取天氣資料使用的是Retrofit架構,它能自動的返回Observable對象。
那麼我們如何通過RxJava擷取本地檔案中的城市列表呢?(為了方便示範,我將城市列表作為一個json字串放於檔案中)

@Override public void getPlaceData() {   PlaceRepository repository = new PlaceRepository();   repository.getPlaceList(BaseApplication.getInstance())       .subscribeOn(Schedulers.io())       .observeOn(AndroidSchedulers.mainThread())       .subscribe(new Subscriber<List<Place>>() {         @Override         public void onNext(List<Place> places) {           mMainView.setupPlaceData(places);         }          @Override         public void onCompleted() {          }          @Override         public void onError(Throwable e) {          }       }); } public class PlaceRepository {    public Observable<List<Place>> getPlaceList(final Context context) {     return Observable.create(new Observable.OnSubscribe<List<Place>>() {       @Override       public void call(Subscriber<? super List<Place>> subscriber) {         try {           AssetManager assertManager = context.getAssets();           InputStream inputStream = assertManager.open("place");           ByteArrayOutputStream outStream = new ByteArrayOutputStream();           byte[] data = new byte[1024];           int count = -1;           while((count = inputStream.read(data,0, 1024)) != -1) {             outStream.write(data, 0, count);           }           String json = new String(outStream.toByteArray(),"UTF-8");           Gson gson = new GsonBuilder().create();           List<Place> placeList = gson.fromJson(json, new TypeToken<List<Place>>() {}.getType());           subscriber.onNext(placeList);         } catch (Exception e) {           subscriber.onError(e);         }         subscriber.onCompleted();       }     });   } } 

通過上述代碼,我們就能完成介面所示功能了,是不是省去了Handler callback,new Thread()這些操作了,這就為什麼說RxJava是用來解決Callback Hell的。

 ”在Activity中分別調用了擷取天氣資料和城市列表的方法,那麼問題來了,如果取資料的時候顯示了process Dialog, 我該在什麼時候結束呢,寫flag判斷?“

     最直接的最暴力的方法就是直接在一個方法裡同步調用兩個介面,那使用RxJava怎麼實現呢?

     這個問題可以使用RxJava的Merge操作符實現,故名思議就是將兩個介面Observable合成一個,廢話不說直接上代碼:

@Override public void getPlaceAndWeatherData(String place) {   mMainView.showProgress();   PlaceRepository repository = new PlaceRepository();   Context context = BaseApplication.getInstance();   Observable placeObservable = repository.getPlaceList(context);   Observable weatherObservable = ServiceManager.getInstance().getApiService().getWeatherInfo(place, Constants.BAIDU_AK);   Observable.merge(placeObservable, weatherObservable)       .subscribeOn(Schedulers.io())       .observeOn(AndroidSchedulers.mainThread())       .subscribe(new Subscriber<Object>() {         @Override         public void onCompleted() {           mMainView.hideProgress();         }          @Override         public void onError(Throwable e) {           mLogger.error(e.getMessage(), e);           mMainView.hideProgress();         }          @Override         public void onNext(Object obj) {           if (obj instanceof List) {             mMainView.setupPlaceData((List<Place>) obj);           } else if (obj instanceof WeatherResponse) {             mMainView.setupWeatherData((WeatherResponse) obj);           }         }       }); } 


這樣就很巧妙的解決了如果取資料的時候顯示process Dialog、該在什麼時候結束、寫flag判斷的問題。

如果這樣的代碼看著還不舒服,你完全可以使用Lambda,這樣可以讓代碼看起來少之又少,不過Android studio目前還不支援Lambda,如果想要使用請安裝外掛程式RetroLambda 並且JDK 使用JDK 8以上版本.

Github源碼地址:https://github.com/mickyliu945/CommonProj

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.