編寫(xiě)簡(jiǎn)易Android天氣應(yīng)用的代碼示例
本文所要介紹的簡(jiǎn)易天氣App主要用RxAndroid、MVP、Retrofit實(shí)現(xiàn),首先來(lái)看看效果:
主頁(yè)內(nèi)容:
右側(cè)欄天氣列表:
左側(cè)欄城市列表
首先看看Activity主要代碼(使用MVP模式):
//調(diào)用Presenter的方法獲取數(shù)據(jù) mMainPresenter = new MainPresenterImpl(this); mMainPresenter.getPlaceData(); mMainPresenter.getWeatherData("成都"); //顯示主頁(yè)和右側(cè)欄天氣數(shù)據(jù) 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(); } } //顯示左側(cè)欄城市列表 @Override public void setupPlaceData(List<Place> placeList) { if (placeList == null) { return; } mPlaceAdapter.setData(placeList); mPlaceAdapter.notifyDataSetChanged(); }
接下來(lái)看看如何在Presenter中應(yīng)用RxJava、RxAndroid獲取數(shù)據(jù)
//獲取天氣數(shù)據(jù) @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); }
如上所述,我們通過(guò)百度api獲取天氣數(shù)據(jù)使用的是Retrofit框架,它能自動(dòng)的返回Observable對(duì)象。
那么我們?nèi)绾瓮ㄟ^(guò)RxJava獲取本地文件中的城市列表呢?(為了方便演示,我將城市列表作為一個(gè)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(); } }); } }
通過(guò)上述代碼,我們就能完成界面所示功能了,是不是省去了Handler callback,new Thread()這些操作了,這就為什么說(shuō)RxJava是用來(lái)解決Callback Hell的。
”在Activity中分別調(diào)用了獲取天氣數(shù)據(jù)和城市列表的方法,那么問(wèn)題來(lái)了,如果取數(shù)據(jù)的時(shí)候顯示了process Dialog, 我該在什么時(shí)候結(jié)束呢,寫(xiě)flag判斷?“
最直接的最暴力的方法就是直接在一個(gè)方法里同步調(diào)用兩個(gè)接口,那使用RxJava怎么實(shí)現(xiàn)呢?
這個(gè)問(wèn)題可以使用RxJava的Merge操作符實(shí)現(xiàn),故名思議就是將兩個(gè)接口Observable合成一個(gè),廢話不說(shuō)直接上代碼:
@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); } } }); }
這樣就很巧妙的解決了如果取數(shù)據(jù)的時(shí)候顯示process Dialog、該在什么時(shí)候結(jié)束、寫(xiě)flag判斷的問(wèn)題。
如果這樣的代碼看著還不舒服,你完全可以使用Lambda,這樣可以讓代碼看起來(lái)少之又少,不過(guò)Android studio目前還不支持Lambda,如果想要使用請(qǐng)安裝插件RetroLambda 并且JDK 使用JDK 8以上版本.
Github源碼地址:https://github.com/mickyliu945/CommonProj
- 用Java實(shí)現(xiàn)全國(guó)天氣預(yù)報(bào)的api接口調(diào)用示例
- ASP.NET使用WebService實(shí)現(xiàn)天氣預(yù)報(bào)功能
- PHP Ajax JavaScript Json獲取天氣信息實(shí)現(xiàn)代碼
- Jquery獲取當(dāng)前城市的天氣信息
- Android天氣預(yù)報(bào)app改進(jìn)版
- PHP微信開(kāi)發(fā)之查詢城市天氣
- js獲取新浪天氣接口的實(shí)現(xiàn)代碼
- JS顯示日歷和天氣的方法
- asp.net實(shí)現(xiàn)根據(jù)城市獲取天氣預(yù)報(bào)的方法
- Android編程實(shí)現(xiàn)獲取新浪天氣預(yù)報(bào)數(shù)據(jù)的方法
- 簡(jiǎn)單易懂的天氣插件(代碼分享)
相關(guān)文章
android studio git 刪除已在遠(yuǎn)程倉(cāng)庫(kù)的文件或文件夾方式
這篇文章主要介紹了android studio git 刪除已在遠(yuǎn)程倉(cāng)庫(kù)的文件或文件夾方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Android網(wǎng)絡(luò)監(jiān)聽(tīng)和網(wǎng)絡(luò)判斷示例介紹
大家好,本篇文章主要講的是Android網(wǎng)絡(luò)監(jiān)聽(tīng)和網(wǎng)絡(luò)判斷示例介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12Android下的CMD命令之關(guān)機(jī)重啟及重啟recovery
這篇文章主要介紹了Android下的CMD命令之關(guān)機(jī)重啟及重啟recovery,本文涉及到cmd命令知識(shí)點(diǎn),通過(guò)了解cmd命令就可以很容易的實(shí)現(xiàn)此功能了,需要的朋友一起看看吧2016-08-08Android ListView獲得選項(xiàng)中的值
本篇文章主要介紹Android ListView,在Android開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)用到ListView 組件并有監(jiān)聽(tīng)事件,這里給大家一個(gè)簡(jiǎn)單實(shí)例,來(lái)說(shuō)明如何得到ListView選項(xiàng)中的值2016-07-07Android開(kāi)發(fā)中匿名設(shè)備標(biāo)識(shí)符OAID使用及初始化
這篇文章主要為大家介紹了Android開(kāi)發(fā)中匿名設(shè)備標(biāo)識(shí)符OAID使用及初始化,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04Android仿拉手網(wǎng)團(tuán)購(gòu)App產(chǎn)品詳情界面效果
這篇文章主要介紹了Android仿拉手網(wǎng)團(tuán)購(gòu)App產(chǎn)品詳情界面效果,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05Android編程實(shí)現(xiàn)手繪及保存為圖片的方法(附demo源碼下載)
這篇文章主要介紹了Android編程實(shí)現(xiàn)手繪及保存為圖片的方法,涉及Android畫(huà)布的使用及圖片的操作技巧,并附帶了demo源碼供讀者下載,需要的朋友可以參考下2015-12-12Android實(shí)現(xiàn)計(jì)步傳感器功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)計(jì)步傳感器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01Android RecyclerView顯示Item布局不一致解決辦法
這篇文章主要介紹了Android RecyclerView顯示Item布局不一致解決辦法的相關(guān)資料,需要的朋友可以參考下2017-07-07