欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2024-02-22 20:01:34
本文所要介绍的简易天气app主要用rxandroid、mvp、retrofit实现,首先来看看效果: 主页内容: 右侧栏天气列表: 左侧栏城市列表...

本文所要介绍的简易天气app主要用rxandroid、mvp、retrofit实现,首先来看看效果:
主页内容:

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

右侧栏天气列表:

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

左侧栏城市列表

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

首先看看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