草庐IT

基于Android实现的天气预测APP

biyezuopinvip 2023-12-12 原文

基于Android开发的天气预测APP

一、相关技术

1.1 网络

网络数据源使用 Retrofit 库访问彩云 API 提供的 Webservice 接口来实现。

Retrofit 通过封装络请求和数据解析,极地提升了开发效率。并且持定义数据解析在封装所有网络请求的 API 时,我使用了协程技术来简化 Retrofit 回调的写法。

1.1.1 数据存储

本地数据源使用 SharedPreferences 持久化技术来实现,使用键值对的方式来存储数据。相较于数据库保存数据,SharedPreferences 操作更加简单,本地需要保存的数据也比较简单。因此 SharedPreferences 更加合适。

1.2 UI

创建 ViewModel 实现 ui 层与 service 层的解耦合

使用滚动控件 RecyclerView,使天气展示界面可以轻松高效地展示大量数据。我提供数据并定义每个列表项的外观,而 RecyclerView 库会根据需要动态创建元素

使用 Fragment,使我的一个单独的 activity 可以合成一个多区域的 UI,并且可以在多个 activity 中再使用。

1.3 全局获取 Context 对象

由于本项目需要在 Activity 以外的很多地方使用 Context 对象。因此我使用Application 类,在应用程序启动的时候,系统就会自动将其进行初始化,以便于我们管理程序内如全局 Context 一样的一些全局的状态信息。

这样就可以以静态变量的形式获取 Context 对象了。

同时项目中还需要在在 AndroidManifest.xml 文件的标签下进行指定自定义的 Application 类。

二、系统功能需求

2.1 需求分析

本项目实现了一个简单的天气信息查询的 APP。作为查询信息类的 APP 为了可以是用户能够及时准确的获取一个城市的天气信息。APP 至少应该具备准确查询城市级天气信息、可以查询多城市天气、可以刷新实时天气这三项基本功能。

由于获取城市天气信息的功能过于复杂,且与本课程学习重点无关。因此,我使用了彩云天气的开放 API 获取城市的天气。该 API 可以获取全球 100 多个国家的城市数据,以及每个城市的实时天气预报信息。经过简单的申请注册即可获取令牌使用。

2.2 功能描述

因此本项目具有:

  • 可以搜索全球大多数国家的各个城市数据;

  • 可以查看全球绝大多数城市的天气信息;

  • 可以自由地切换城市,查看其他城市的天气;

  • 可以手动刷新实时的天气。

  • 这四大主要功能,足以满足用户日常查询天气的需求。

三、系统设计与实现

3.1 总体设计

在本项目中,我使用了 MVVM 架构模式。MVVM 架构将程序结构主要分为 Model、View、ViewModel 三个模块。其中 Model 是数据模型部分;View 是界面展示部分;而 ViewModel 实现了业务逻辑和界面展示的解耦合。

  • MVVM项目架构示意图

  • UI 控制层包含了平时写的 Activity、Fragment、布局文件等与界面相关的展示代码。

  • ViewModel 层用于对 UI 元素相关的数据进行持久化,同时 ViewModel 层还提供了接口给 UI 控制层调用以及和 model 层进行通信。

  • Model 层用于判断调用方请求的数据应该是从本地数据源中获取还是从网络数据源中获取,并将获取到的数据返回给调用方。实现了 APP 所必须的逻辑处理功能。

3.2 系统组成

按照 MVVM 架构的设计,我在项目中将设计业务逻辑处理(model 层)的代码放在 service 包,并且将界面展示部分(view 层)代码放在 ui 包中。

3.3 模块设计

3.3.1 service 模块

在 logic 包下新建一个 Repository 单例类,作为仓库层的统一封装入口。使用liveData()将异步获取的数据以响应式编程的方式通知给上一层。同时我将liveData()函数的线程参数类型指定成了 Dispatchers.IO 使这段网络请求代码运行在子线程。

在 logic/model 包下新建一个 Sky.kt 文件,定义了一个 Sky 类作为数据模型表示该天气情况所对应的文字、图标和背景。然后使用 mapOf()函数来定义每种天气代码所应该对应的文字、图标和背景。

在 logic/model 通过 PlaceResponse.kt 文件定义数据模型实现对城市位置信息的映射。

在 logic/model 包下新建一个 RealtimeResponse.kt 文件定义数据模型实现对当前天气信息的映射。

在 logic/model 包下新建一个 DailyResponse.kt 文件定义数据模型实现对预测天气信息的映射。

在 logic/model 包下定义一个 Weather 类,将 Realtime 和 Daily 对象封装起来。

在 logic/network 包下新建一个 ServiceCreator 单例类,创建了一个 Retrofit 构建器。

在 logic/network 包下新建 PlaceService 接口,定义一个用于访问彩云天气城市搜索 API 的 Retrofit 接口。

该函数的返回值为 Call,这样 Retrofit 就会将服务器返回的 JSON 数据自动解析成 PlaceResponse 对象了。

在 logic/network 包下新建 WeatherService 接口定义一个用于访问天气信息 API 的 Retrofit 接口。

在 logic/network 包下新建一个 SunnyWeatherNetwork 单例类,定义一个统一的网络数据源访问入口,对所有网络请求的 API 进行封装。

并自定义的 await()函数调用 suspendCoroutine 函数简化回调过程。

在此当外部调用 SunnyWeatherNetwork 所提供的函数时,Retrofit 就会立即发起网络请求,同时当前的协程也会被阻塞住。直到服务器响应我们的请求之后,await()函数会将解析出来的数据模型对象取出并返回,同时恢复当前协程的执行,searchPlaces()函数在得到 await() 函数的返回值后会将该数据再返回到上一层。

在 logic/dao 包下新建一个 PlaceDao 单例类封装了几个必要的存储和读取数据的接口,将Place 对象存储到 SharedPreferences 文件中,并编写一些涉及 SharedPreferences 的操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rBl0cYvN-1662615514250)(https://www.writebug.com/myres/static/uploads/2022/9/8/339af5cac748f041bf0888002e73bfd3.writebug)]

3.3.2 ui 模块

实现搜索城市界面:

  • 在 ui/place 包下新建一个 PlaceViewModel,定义搜索城市界面的 ViewModel 层。

  • 在 ui/place 包下新建一个 PlaceAdapter 类为 RecyclerView 准备适配器。

  • 在 ui/place 包下新建一个 PlaceFragment 对 Fragment 进行实现。

实现天气展示界面:

  • 在 ui/weather 包下新建一个 WeatherViewModel,定义天气展示的 ViewModel 层。

  • 在 ui/weather 包下新建一个 WeatherActivity,显示天气信息的 Activity

有关基于Android实现的天气预测APP的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  3. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  4. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  7. ruby - 使用 postgres.app 在 rvm 下要求 pg 时出错 - 2

    我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension

  8. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  9. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  10. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

随机推荐