编写简易Android天气应用的代码示例

本文所要介绍的简易天气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

(0)

相关推荐

  • asp.net实现根据城市获取天气预报的方法

    本文实例讲述了asp.net实现根据城市获取天气预报的方法.分享给大家供大家参考,具体如下: public void GetWetheaerByCity(string cityName) { string city = cityName; string mycity = HttpUtility.UrlEncode(city, System.Text.Encoding.GetEncoding("GB2312")); System.Net.HttpWebRequest request =

  • js获取新浪天气接口的实现代码

    js获取新浪天气接口的实现代码 <!doctype html> <html class="no-js fixed-layout"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>天气</title> </

  • PHP Ajax JavaScript Json获取天气信息实现代码

    要在自己的网站上添加一个天气预报功能,是一个很普通的需求,实现起来也不是很难.今天来介绍几个简单的方法. 使用第三方服务 有这样的一种简单的方式,借助http://www.tianqi.com/plugin/网上的天气服务,可以定制我们的显示形状,实现添加天气预报的功能. 下面给出一个简单的小例子: 复制代码 代码如下: <iframe width="420" scrolling="no" height="60" frameborder=&

  • Jquery获取当前城市的天气信息

    本文实例为大家分享了Jquery获取当前城市的天气信息代码,供大家参考,具体内容如下 HTML代码: <div id="weather"></div> Jquery代码: function findWeather() { var cityUrl = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js'; $.getScript(cityUrl, function(script, textSt

  • 简单易懂的天气插件(代码分享)

    效果图如下: 代码如下所示: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>天气</title> <meta name="viewport" content="width=device-width,initial-scale=1"/> <style type="text/cs

  • Android编程实现获取新浪天气预报数据的方法

    本文实例讲述了Android编程实现获取新浪天气预报数据的方法.分享给大家供大家参考,具体如下: 新浪天气预报地址: http://php.weather.sina.com.cn/xml.php?city=武汉&password=DJOYnieT8234jlsK&day=0 其中,city后的城市可用java.net.URLEncoder.encode("武汉"," gb2312");也可以直接写"武汉",但不能用"wu

  • JS显示日历和天气的方法

    本文实例讲述了JS显示日历和天气的方法.分享给大家供大家参考,具体如下: 运行效果截图如下: 完整代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml&qu

  • Android天气预报app改进版

    最近总是有人来和我说我以前写的一个小app无法正常获取数据~Android简易版天气预报app 今天就又运行了下来查找问题,发现或许是接口有限制吧,不能在多台手机使用同个apikey 然后,发现了我写的代码实在乱七八糟,界面也实在不好看,就又重写了一遍,小小地修改了一遍,开发环境改为了Android Studio 最终效果图如下 工程图如下 一.获取地区信息 做这么一个天气预报app,首先就要获取到国内地区列表 (在我的另一篇博客有介绍:向任意网址发起数据请求) 中国天气网开放有天气预报接口,访

  • PHP微信开发之查询城市天气

    PHP微信查询城市天气,首先,你需要找到一个获取天气的API,此处,我用的是百度的apistore,申请和使用API的网址:http://apistore.baidu.com/apiworks/servicedetail/112.html 登录百度账号,并用手机发送请求获取apikey.有了apikey,可以按照它的示例来请求城市天气了.(可以按照城市中文名,拼音,城市编号等来查询) 你可以现在本地做测试,请求完成之后,再放到自己的域名空间的脚本里.  测试的脚本例如:(注意apikey填写自己

  • 用Java实现全国天气预报的api接口调用示例

    step1:选择本文所示例的接口"全国天气预报接口" 聚合数据url:http://www.juhe.cn/docs/api/id/39/aid/87 step2:每个接口都需要传入一个参数key,相当于用户的令牌,所以第一步你需要申请一个key. step3:学过java的同学们都知道,当我们对一个类或者方法不明白其意图和思想时,我们可以去查看文档,这里也不例外,而且对于英文不是特别好的同学来说很幸运的是,聚合网站上的文档都是中文版本的,比起阅读java源码里的英文文档应该轻松很多.

  • ASP.NET使用WebService实现天气预报功能

    本文使用Asp.Net (C#)调用互联网上公开的WebServices(http://www.webxml.com.cn/WebServices/WeatherWebService.asmx)来实现天气预报,该天气预报 Web 服务,数据来源于中国气象局http://www.cma.gov.cn/,数据每2.5小时左右自动更新一次,准确可靠.包括 340 多个中国主要城市和 60 多个国外主要城市三日内的天气预报数据. 效果图 : 步骤 : 1 .新建web 项目,添加窗体. 2 . 引用右键

随机推荐