安卓实战项目 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

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模