安卓实战项目 Sunny天气App

2023-11-04 05:50

本文主要是介绍安卓实战项目 Sunny天气App,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介:

学了一段时间的安卓了,最近准备跟着 第一行代码 这本书做一个较为完整的App项目,巩固一下所学到的知识。现在 第一行代码 这本书已经出到第三版了,里面是使用Kotlin进行开发的。但我平时还是Java用的比较多点,因此,我就想使用Java 来实现第三版中的 SunnyWeather 天气预报APP。下面就是关于这次项目的一些学习笔记。


1.准备工作

实现的功能和所需的技术要点都在书 P601页上有详细描述,这里就不再哆嗦了。在工作开始之前,先得按照书上描述,申请开放的天气API 接口,提交申请后,大概需要3~4个工作日才能通过审核。
如果之前使用的是第二版进行学习的同学,可能还需要了解一些第二版中没有提到的一些新内容。主要就是网络请求框架Retrofit、Jetpack中的ViewModel和LiveData 这些内容。

虽然安卓应用同时支持Java和Kotlin进行开发,但使用Kotlin代码编写的部分操作,在使用Java进行重写的时候,还是会出现一些问题,下面就是对出现的部分问题的一些说明。


2.问题说明

2.1 网络请求同步的问题

这是一个比较棘手的问题。到最后,我也没有能够完美解决。在实际开发中,我们常常需要发起网络请求,并将请求到的数据赋给一个实例,然后再进行一系列,如数据处理,UI更新等操作,但我在开发过程中,却遇到了 还没等到网络请求操作,程序就先进行数据操作 这种问题。
下面是项目中的具体例子,方便我们理解这个问题。(相关代码可见项目Repository类和SunnyNetWork类)

//获取到对应的数据模型类的实例,返回的数据不为null
final PlaceResponse placeResponse = sunnyWeatherNetwork.searchPlaces(query);
if (placeResponse.getStatus().equals("ok")) {places = placeResponse.getPlaces();// 获取到包含地区信息的listLog.d("Repository","place response success " );placesData.postValue(places);//将list传入Livedata内,并准备返回
} else {//返回状态不是ok的情况Log.d("Repository", "place status is" + placeResponse.getStatus() );
}

上面是项目中实现搜索地区数据信息功能的部分代码。首先, sunnnyWeatherNetwork .searchPlaces 这个方法中封装了网络请求操作以及空指针检测,返回获取到的数据并保证数据不为null。我们调用该方法,并把返回值赋给 placeResponse 。随后我们对placeResponse中的 status 值进行判断,如果为“ok”, 则进行一些数据处理操作,否则,则打印错误信息。
逻辑上来看,这段代码不难理解,而且在实现上应该没有什么问题。但实际上却存在空指针异常或是数据错误等问题。
下面是对项目进行调试时的记录日志:

调试记录
我们从上面的调试记录中可以看到,仓库层(Repository)已经进行完数据处理了,网络请求才完成。这样导致的后果就是取得的 placeResponse 为空或者为null。我自己思考的结论是,问题出现的原因是:进行网络请求时,Restrofit 会 new 一个线程,在另一个线程中进行网络请求,这样的结果就是仓库层的线程和网络请求线程并发执行,导致出现:没等网络请求成功响应,程序就进一步执行的情况。


解决方案:
在Kotlin中,我们可以使用async函数和await()方法,来实现同步。但我在用Java编写时,由于水平不足,没有很好地解决同步问题,因此会出现这样的问题:进行网络请求时,第一次网络请求得到的结果,是错误的,需要丢弃。

在搜索地区信息功能模块中,该问题导致搜索框体验不佳,需要在输入 想要搜索的地区信息后,再按下其他键。(等于发起第二次请求)才能搜索到结果。
输入北京后,需要在输入一个任意按键,才能正确显示结果
可以看到,输入北京后,还需要再输入任意一个按键,才能正确显示结果。

在天气信息显示功能中,为了解决这个问题,我就写了个循环,隔一小段时间就进行一次网络请求,直到返回的对象不为空时,再跳出循环。

do {//realtimeResponse 和 dailyResponse通过调用封装的网络请求方法获取realtimeResponse = sunnyWeatherNetwork.getRealtimeWeather(lng, lat);dailyResponse = sunnyWeatherNetwork.getDailyWeather(lng, lat);Log.d("Repository","refresh Weather 数据申请中");sleep(500);
}while (realtimeResponse == null || dailyResponse == null);//只有两个不为null时才跳出循环

这些方法只是暂时的解决,应该可以通过线程同步等方式的到更好的解决。

2.2 其他问题

1.项目中显示的文字均采用硬编码的写法。更合理的做法应该是定义在String.xml 中,然后在布局中引用。
2.编码不够规范。变量定义还不够规范(例如很多变量声明时未加上final),部分文档也没写清楚,代码自我感觉比较乱。
3.搜索界面中,状态栏与搜索框颜色不同,略显违和
4.部分机型兼容问题。在实现背景图与状态栏融合的效果时,在Android Studio 上的Pixel4上进行测试时,会发生图标折叠的情况。然而在实体机上,却不会出现这种情况。
在这里插入图片描述
5.天气api令牌值的引用存在问题。在PlaceService中可以通过代码 ${SunnyWeatherApplication.TOKEN} 来取得令牌值,但在WeatherService 中使用相同的引用方法,却提示令牌错误。最后我也没发现是什么原因导致的,只能在WeatherService中显式的填入令牌值才解决问题。


3.后续可扩展功能

1.修复上述提到的问题
2.实现后台更新天气信息
3.通过位置信息,自动选择城市
4.适配深色主题


4.源码链接

下面是这次实战项目的源码链接,希望能给有需要学习的同学提供一点帮助吧。

Sunny天气源码链接

这篇关于安卓实战项目 Sunny天气App的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/343661

相关文章

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志

《SpringBoot项目配置logback-spring.xml屏蔽特定路径的日志》在SpringBoot项目中,使用logback-spring.xml配置屏蔽特定路径的日志有两种常用方式,文中的... 目录方案一:基础配置(直接关闭目标路径日志)方案二:结合 Spring Profile 按环境屏蔽关

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

springboot项目中使用JOSN解析库的方法

《springboot项目中使用JOSN解析库的方法》JSON,全程是JavaScriptObjectNotation,是一种轻量级的数据交换格式,本文给大家介绍springboot项目中使用JOSN... 目录一、jsON解析简介二、Spring Boot项目中使用JSON解析1、pom.XML文件引入依

使用vscode搭建pywebview集成vue项目实践

《使用vscode搭建pywebview集成vue项目实践》:本文主要介绍使用vscode搭建pywebview集成vue项目实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录环境准备项目源码下载项目说明调试与生成可执行文件核心代码说明总结本节我们使用pythonpywebv

Java Spring 中的监听器Listener详解与实战教程

《JavaSpring中的监听器Listener详解与实战教程》Spring提供了多种监听器机制,可以用于监听应用生命周期、会话生命周期和请求处理过程中的事件,:本文主要介绍JavaSprin... 目录一、监听器的作用1.1 应用生命周期管理1.2 会话管理1.3 请求处理监控二、创建监听器2.1 Ser

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

Maven项目中集成数据库文档生成工具的操作步骤

《Maven项目中集成数据库文档生成工具的操作步骤》在Maven项目中,可以通过集成数据库文档生成工具来自动生成数据库文档,本文为大家整理了使用screw-maven-plugin(推荐)的完... 目录1. 添加插件配置到 pom.XML2. 配置数据库信息3. 执行生成命令4. 高级配置选项5. 注意事