当前位置: 首页 > news >正文

Android Studio可直接运行的天气预报App开发包:含源码、APK、论文与导入实操指南

本文还有配套的精品资源,点击获取

简介:这个资源包提供一个功能完整的安卓天气预报应用,安装app-debug.apk就能在手机或模拟器上立刻查看实时天气、城市切换和定位效果。项目基于Android Studio开发,源码结构清晰,包含XML界面布局、Activity业务逻辑、OkHttp或Retrofit网络请求、Gson数据解析、LocationManager定位模块,以及天气图标、温度、湿度、风速等信息的展示逻辑。配套文档《基于Android天气预报系统设计与实现.docx》涵盖需求分析、技术选型依据、模块功能说明、程序流程图和关键代码片段;另一份《导入项目教程.docx》详细列出Android Studio中打开项目的每一步操作,包括Gradle版本匹配、SDK路径配置、JDK设置、签名文件处理及常见报错解决方案。所有配置文件齐全:build.gradle支持一键构建,settings.gradle适配多模块,proguard-rules.pro已预置混淆规则,gradle.properties含常用参数定义。整个工程无需额外改造即可编译运行,适合课程设计、毕业设计快速上手,也适合作为Android入门者练手的真实项目案例。

1. 这不是Demo,是能直接装进手机里看天气的完整项目

你有没有试过在B站或CSDN上搜“Android天气App源码”,点开十几个链接,结果全是只有MainActivity.java和一个空布局文件的半成品?或者下载下来发现gradle版本是3.5,而你的AS已经升到8.2,Sync失败十次,报错堆栈比天气预报还长?又或者好不容易跑起来了,一点击“定位”就闪退,Logcat里只有一行java.lang.SecurityException: Neither user 10123 nor current process has android.permission.ACCESS_FINE_LOCATION——连权限都没配全,更别说城市切换、天气图标动态加载这些基础功能了。

这个资源包,就是为解决这些真实痛点而生的。它不是一个教学PPT里的伪代码截图,也不是GitHub上star数很高但实际跑不起来的“概念验证项目”。它是一套经过真机实测、模拟器多版本验证、Gradle全链路构建通过的可交付成果。你拿到手,解压,双击app-debug.apk,就能在小米13或Pixel 4a上看到当前城市的温度、湿度、风速、天气图标,还能手动输入“杭州”“成都”切换城市,点击“定位”按钮后3秒内刷新出你所在位置的实时天气——整个过程不需要改一行代码,不需要查文档,不需要百度“Failed to resolve: androidx.appcompat:appcompat”。

核心关键词我再强调一遍:安卓天气App、Android源码、天气预报系统、APK安装包、Android Studio教程。这五个词不是标签,而是五个硬性交付物:
- “安卓天气App” → 指它具备真实可用的交互逻辑,不是静态界面;
- “Android源码” → 指结构符合Android官方推荐规范(app模块独立、res资源分类清晰、Java/Kotlin分层合理);
- “天气预报系统” → 指它包含完整的数据流闭环:定位/输入 → 请求API → 解析JSON → 更新UI → 缓存策略;
- “APK安装包” → 指它是debug签名、未混淆、支持armeabi-v7a+arm64-v8a双架构的可安装产物;
- “Android Studio教程” → 指它不假设你熟悉Gradle生命周期,连“如何找到File → Project Structure → SDK Location”这种操作都配有截图级指引。

我带过三届毕业设计,每年都有学生卡在“导入项目就红屏”这一步。有人花三天配环境,最后答辩前两天才跑出第一个Toast;有人抄了网上的Retrofit示例,却没注意到服务端返回的是{"data":{"city":"北京","weather":"晴","temp":"23℃"}},而他的Gson解析写成了new Gson().fromJson(json, Weather.class),导致data字段永远为null——这些坑,这个包里全都提前踩过、填平、标好警示牌。它不是教你从零造轮子,而是给你一辆油已加满、轮胎已打气、后视镜已调好、连说明书都印在方向盘上的车。你唯一要做的,就是坐上去,系好安全带,拧钥匙启动。

2. 项目整体设计与思路拆解:为什么这样组织,而不是用Jetpack Compose或Kotlin协程?

很多人看到“Android天气App”第一反应是:“现在谁还用XML写界面?早该上Compose了!”或者“Retrofit+协程才是现代写法,OkHttp太老了!”——这种想法没错,但在课程设计、毕设、入门实战这三个具体场景下,它恰恰是最大的认知陷阱。这个项目的整体架构,不是技术选型的炫技,而是对教学有效性、环境兼容性、调试可见性三重约束下的最优解。下面我一条条拆给你看。

2.1 UI层:坚持XML+Activity,放弃Compose的底层逻辑

项目采用传统的activity_main.xml+MainActivity.java组合,而非Jetpack Compose。这不是因为作者不会写@Composable函数,而是因为:

  • 调试成本差异巨大:在XML中,一个TextView显示异常,你一眼就能看出是android:textSize="12sp"写成了"12dp",或者android:layout_below="@id/title"指向了不存在的ID;而在Compose里,Text(text = weather?.temp ?: "—", fontSize = 12.sp)中的12.sp如果写成12.dp,编译不报错,运行时字体小得看不见,Logcat里没有任何提示,新手会卡死在“为什么文字不显示”这个问题上超过两小时。
  • AS版本兼容性现实:Compose要求Android Studio Giraffe(2022.3.1)及以上,而高校机房、学生笔记本普遍还在用Flamingo(2022.2.1)甚至Electric Eel(2022.1.1)。我们测试过,在Flamingo上新建Compose项目,Gradle Sync会卡在Resolving dependencies长达8分钟,且90%概率失败。而XML项目在任意AS 4.0+版本上都能秒Sync。
  • 教学路径平滑:学生先理解findViewById(R.id.temp_text).setText(weather.temp)这种显式绑定,再过渡到ViewBinding,最后才是@Composable的声明式思维。跳过中间层直接上Compose,就像教人游泳不先练憋气,直接扔进深水区。

提示:项目中所有XML布局均采用ConstraintLayout,避免嵌套过深。例如天气卡片使用app:layout_constraintTop_toBottomOf="@id/city_name"而非LinearLayout的android:layout_marginTop,既保证性能,又为后续迁移到Compose预留语义化锚点。

2.2 网络层:OkHttp为主,Retrofit为辅,明确分工

源码中网络请求模块实际包含两套实现:主流程用OkHttp同步请求封装(WeatherApiManager.java),而城市搜索建议功能则调用Retrofit异步接口(SuggestionService.java)。这不是代码混乱,而是精准匹配不同场景:

  • 天气主数据必须强一致性:用户点击“定位”后,必须等待天气数据完全返回并解析成功,才能更新UI。OkHttp的execute()方法天然阻塞主线程,配合AsyncTask(虽已废弃但教学友好)或HandlerThread,逻辑清晰、断点易设。你可以在OkHttpClient.newCall(request).execute()这一行打个断点,看着Response Body一步步变成Java对象,全程可控。
  • 城市搜索需响应及时性:用户在EditText里每输入一个字,都要触发搜索建议。Retrofit+RxJava或协程更适合这种高频、非关键路径的异步调用。项目中SuggestionService使用Retrofit,是因为其@GET("suggestion")注解+Call<List<Suggestion>>返回类型,比手写OkHttp的RequestBody.create()+Response.body().string()更贴近HTTP语义,学生更容易理解“请求路径”“查询参数”“JSON数组解析”之间的映射关系。

注意:所有网络请求均配置了超时(connectTimeout=15s, readTimeout=20s),并内置重试机制(失败后自动重试1次)。这是真实项目必备,而非教学Demo的“理想环境假设”。

2.3 定位层:LocationManager+被动定位兜底,不依赖Google Play服务

项目使用LocationManager而非FusedLocationProviderClient,原因很实在:
-国内真机无Play服务:华为Mate 50、小米14等设备默认禁用Google服务框架,FusedLocationProviderClient初始化直接返回nullgetLastLocation()永远抛SecurityException。而LocationManager是Android原生API,只要用户授予定位权限,GPS_PROVIDERNETWORK_PROVIDER即可工作。
-教学调试友好LocationManager.requestLocationUpdates()的回调中,你可以直接打印location.getLatitude()location.getLongitude(),数值真实可验。我们甚至在README.md里写了如何用Android Studio的Emulator Extended Controls手动发送经纬度(如39.9042,116.4074模拟北京天安门),学生立刻能看到“北京市”“晴”“23℃”出现在屏幕上,成就感来得非常直接。
-被动定位兜底:项目额外注册了PASSIVE_PROVIDER,当其他应用(如高德地图)获取到定位时,本App也能收到广播。这解决了“首次打开App时GPS未冷启动,定位失败”的常见问题——很多学生以为自己代码错了,其实是手机还没搜到卫星信号。

2.4 数据解析:Gson定制TypeAdapter,而非泛型反射

天气API返回的JSON结构往往不规整:温度可能是字符串"23℃",也可能是数字23;风向可能是中文"东北风",也可能是英文缩写"NE";甚至同一字段在不同城市返回类型不一致(如humidity有时是"65%",有时是65)。如果直接用Gson.fromJson(json, Weather.class),Gson的默认反射机制会因类型不匹配而静默失败,Weather.humidity始终为0。

项目中为此专门编写了WeatherTypeAdapter.java,继承TypeAdapter<Weather>,重写read(JsonReader reader)方法:

if ("humidity".equals(fieldName)) { String value = reader.nextString(); if (value.endsWith("%")) { weather.setHumidity(Integer.parseInt(value.substring(0, value.length()-1))); } else { weather.setHumidity(Integer.parseInt(value)); } }

这种写法看似繁琐,但对学生而言价值极大:它强制暴露了“JSON字段名→Java字段→类型转换规则”这一完整链条。比起黑盒式的@SerializedName注解,学生能真正理解“为什么这里要手动处理”,并在未来遇到类似问题(如时间戳格式混乱)时,知道该去哪里改。

3. 核心细节解析与实操要点:从APK安装到源码结构的每一处关键

拿到资源包,第一步不是急着打开Android Studio,而是先验证最底层的交付物是否完整可用。这个环节省掉的十分钟,可能帮你避开后面三小时的无效排查。下面我把从解压到真机运行的全流程,拆解成可逐项核对的实操要点,并标注每个步骤背后的原理和常见陷阱。

3.1 APK安装包:不只是能装,更要懂它为什么能装

资源包里的app-debug.apk不是随便Build → Generate Signed Bundle/APK出来的。它的生成过程经过了四层校验:

  1. 签名配置合规app/build.gradle中明确配置了debug keystore:
    gradle android { signingConfigs { debug { storeFile file("../debug.keystore") storePassword "android" keyAlias "androiddebugkey" keyPassword "android" } } buildTypes { debug { signingConfig signingConfigs.debug } } }
    这确保了APK使用标准Android Debug Key签名,任何开启了“USB调试”的Android设备都能直接安装(无需手动开启“未知来源”)。如果你用的是自定义keystore,设备会弹出“此应用未经Google Play验证”的警告,学生容易误以为APK损坏。

  2. 架构兼容性预置app/src/main/jniLibs/目录下同时存在armeabi-v7a/arm64-v8a/两个文件夹,内含天气图标解码所需的libpng.so等本地库。这意味着它能在骁龙8 Gen2(arm64)和麒麟990(armeabi-v7a)设备上均正常显示天气图标。我们曾测试过,若只放arm64-v8a,华为P40 Pro(搭载麒麟990)安装后图标全显示为方块——因为系统找不到对应架构的so库。

  3. 权限声明完备AndroidManifest.xml中不仅声明了基础权限:
    xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    还特别添加了<application android:usesCleartextTraffic="true">。这是因为天气API测试接口(如http://api.openweathermap.org/data/2.5/weather)多数仍用HTTP而非HTTPS。Android 9.0+默认禁止明文流量,不加此声明,请求会直接被系统拦截,Logcat只显示Cleartext HTTP traffic to api.xxx.com not permitted,新手根本看不懂。

  4. 安装验证三步法
    -Step 1:ADB安装验证
    在命令行执行:
    bash adb install -r app-debug.apk
    若返回Success,说明APK签名、架构、清单文件均无硬伤。若报错INSTALL_FAILED_NO_MATCHING_ABIS,说明设备CPU架构与APK不匹配(如x86模拟器装了arm64 APK),此时应检查app/build.gradle中的ndk.abiFilters配置。
    -Step 2:真机运行观察
    打开App,立即点击右上角“定位”按钮。观察状态栏是否出现定位图标(📍),2秒后主界面是否刷新出城市名和温度。若一直显示“定位中…”,长按Home键切到设置→应用→本App→权限→位置,确认已开启。
    -Step 3:Logcat抓取关键日志
    在Android Studio底部打开Logcat,筛选器设为com.example.weather(包名),触发一次定位。正常流程应输出:
    D/WeatherApi: Request URL: http://api.xxx.com/weather?lat=39.9042&lon=116.4074
    D/WeatherParser: Parse success, temp=23℃, humidity=65
    若无Parse success日志,说明网络请求失败或JSON解析异常,需回溯OkHttp配置。

3.2 源码结构:不是文件堆砌,而是教学逻辑的物理呈现

项目目录树看似普通,但每个文件夹的命名和内容都服务于教学目的。以LOGMSrxOGQugEVVr06MX-master-91dd83599eec3f833ff0e813a205d0d74dd4292d/(实际项目根目录)为例,关键结构解析如下:

目录/文件教学作用学生易错点
app/src/main/java/com/example/weather/所有业务代码集中地。MainActivity.java是入口,WeatherApiManager.java封装网络,WeatherParser.java处理JSON,LocationHelper.java管理定位——命名直白,降低认知负荷。学生常把WeatherParser.java误当成工具类,试图在MainActivitynew WeatherParser(),却忘记它需要传入Context。实际应通过WeatherParser.getInstance(context)单例获取。
app/src/main/res/layout/包含activity_main.xml(主界面)、item_city.xml(城市列表项)、dialog_city_input.xml(城市输入对话框)。所有XML均使用tools:text属性预设示例文本(如tools:text="北京市"),AS预览窗口可直接看到效果,无需运行。学生复制代码时,常遗漏xmlns:tools="http://schemas.android.com/tools"命名空间,导致预览空白且无报错。
app/src/main/res/drawable/存放所有天气图标:weather_sunny.pngweather_rainy.png等。图标尺寸严格按mdpi(48x48)、hdpi(72x72)、xhdpi(96x96)、xxhdpi(144x144)四套提供。若只放一套,高分辨率屏幕会模糊或拉伸。学生替换图标时,常把weather_cloudy.png误命名为cloudy.png,导致R.drawable.weather_cloudy找不到资源,编译报错。
app/src/main/assets/内置cities.json离线城市数据库(含全国300+城市ID与名称映射)。当网络不可用时,城市搜索框可从本地加载候选城市,避免“无网络=功能瘫痪”。学生修改此文件后,忘记在AS中右键→Synchronize 'assets',导致新数据不生效。

提示:settings.gradle中仅包含include ':app',未引入任何第三方模块(如:library)。这是刻意为之——课程设计要求“单一模块、结构清晰”,避免学生陷入Module 'xxx' depends on module 'yyy'的循环依赖迷宫。

3.3 配套文档:不是说明书,而是避坑地图

两份Word文档的价值,远超其页数总和:

  • 《基于Android天气预报系统设计与实现.docx》的核心价值在于程序流程图(第12页)和关键代码片段对比表(第28页)。流程图用标准UML活动图绘制,从“用户点击定位”开始,经“检查权限→请求定位→获取坐标→调用API→解析JSON→更新UI”共7个节点,每个节点旁标注对应代码行号(如“请求定位→LocationHelper.java 第45行”)。学生调试时,可对照流程图快速定位卡点。
    关键代码片段表则列出5组“错误写法 vs 正确写法”,例如:
    | 错误写法 | 正确写法 | 原因 |
    |----------|----------|------|
    |textView.setText(temp + "℃");|textView.setText(String.format("%s℃", temp));| 避免temp为null时崩溃 |

  • 《导入项目教程.docx》的精髓在于错误代码截图+解决方案。它收录了12个真实报错场景,如:

  • 报错:Could not find method kotlin() for arguments [...]
    截图:AS顶部Gradle面板红色报错框
    方案:打开gradle/wrapper/gradle-wrapper.properties,将distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip改为gradle-7.2-bin.zip(因项目使用Kotlin 1.6.21,需Gradle 7.2+)
  • 报错:Failed to find target with hash string 'android-33'
    截图:AS弹窗提示“SDK Platform 33 not installed”
    方案:打开File → Settings → Appearance & Behavior → System Settings → Android SDK,勾选Android 13.0 (Tiramisu)并安装

这两份文档不是让你从头读完,而是当你遇到问题时,像查字典一样翻到对应页码,30秒内找到答案。这才是工程文档该有的样子。

4. 实操过程与核心环节实现:从零导入到功能验证的完整链路

现在,我们进入最硬核的部分:手把手带你走完从解压资源包到真机运行的每一步。这不是AS菜单的罗列,而是聚焦每个操作背后的技术意图、参数选择依据、以及一步错步步错的关键阈值。我会以一个从未接触过Android开发的学生视角,还原真实操作现场。

4.1 环境准备:不是装最新版AS,而是装“项目亲和版”

很多学生一上来就去官网下载Android Studio最新版(如2023.3.1),结果Sync失败。原因很简单:这个天气项目基于Android Gradle Plugin 7.2.2构建,它要求Gradle版本为7.3.3,而AS最新版默认捆绑Gradle 8.0+。版本错配会导致Could not resolve all files for configuration ':app:debugRuntimeClasspath'这类玄学错误。

正确做法是:
1. 访问Android Studio历史版本下载页,下载Android Studio Flamingo | 2022.2.1(发布于2023年3月)。这个版本默认Gradle为7.4,与项目完美匹配。
2. 安装时取消勾选“Install Android Virtual Device”,因为我们要用真机调试,AVD反而占用内存。
3. 首次启动AS,选择“Do not import settings”,避免旧版本配置污染新项目。

提示:Flamingo版本在Windows上安装路径默认为C:\Users\<用户名>\AppData\Local\Android\Studio Flamingo,其中AppData是隐藏文件夹,需在文件资源管理器地址栏手动输入路径才能看到。这点在《导入项目教程.docx》第3页有详细截图。

4.2 项目导入:不是Open,而是Import Project(Gradle)

这是学生最容易犯错的一步。AS界面上有三个相似选项:
-Open:用于打开已存在的AS项目(即已有.idea文件夹)
-Import Project (Gradle, Eclipse, etc.):用于导入源码包(无.idea,只有build.gradle
-Check out project from Version Control:用于从Git克隆

本项目属于第二种。操作路径:
1. 启动AS →New Project界面右下角 →Import project (Gradle, Eclipse, etc.)
2. 浏览到解压后的根目录(即包含build.gradlesettings.gradleapp/的文件夹),不要选中app/子文件夹!选中根目录后点击OK。
3. AS会弹出Import Project对话框,保持默认选项(Use gradle wrapper wrapper from the project),点击OK。

此时AS开始Sync,底部状态栏显示Gradle sync in progress...。正常耗时约90秒(取决于网络)。若卡在Resolving dependencies超过5分钟,立即检查:
- 是否开启了代理?关闭系统代理或AS内的HTTP Proxy(Settings → Appearance & Behavior → System Settings → HTTP Proxy设为No proxy
-gradle/wrapper/gradle-wrapper.propertiesdistributionUrl是否被篡改?应为https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip

Sync成功后,项目结构视图中会出现app模块,且app/src/main/java下有绿色com.example.weather包名——这是项目导入成功的视觉标志。

4.3 关键配置修正:三处必改,否则编译必败

即使Sync成功,直接Run也会失败。必须手动修正以下三处配置,它们分散在不同文件中,缺一不可:

4.3.1 JDK版本锁定:防止AS自动升级引发兼容性问题

AS Flamingo默认使用JDK 17,但本项目build.gradle中指定sourceCompatibility JavaVersion.VERSION_11。若不锁定,编译时会报错error: invalid source release: 17

修正路径:
1.File → Project Structure → SDK Location→ 右侧JDK location旁点击...
2. 选择Embedded JDK (jbr-11.0.17)(AS自带的JDK 11)
3. 点击ApplyOK

验证:在app/build.gradle中找到compileOptions块,确认sourceCompatibilitytargetCompatibility均为JavaVersion.VERSION_11

4.3.2 SDK路径显式声明:避免AS读取错误的ANDROID_HOME

某些学生电脑上曾安装过旧版Android SDK,环境变量ANDROID_HOME指向C:\Users\XXX\AppData\Local\Android\Sdk_old,而AS Flamingo实际使用C:\Users\XXX\AppData\Local\Android\Sdk。若不显式声明,Gradle会去旧路径找platforms\android-33,报错Failed to find target with hash string 'android-33'

修正路径:
1. 打开项目根目录下的local.properties文件(若不存在,新建一个)
2. 添加两行:
sdk.dir=C\:\\Users\\<你的用户名>\\AppData\\Local\\Android\\Sdk ndk.dir=C\:\\Users\\<你的用户名>\\AppData\\Local\\Android\\Sdk\\ndk\\23.1.7779620
(注意:路径中的\需双写,<你的用户名>替换成实际用户名)
3. 保存文件,AS会自动触发Gradle Sync。

4.3.3 签名配置启用:让Debug APK可安装

app/build.gradle中虽已配置debug signingConfig,但AS默认不启用。若不手动开启,Run时会报错Execution failed for task ':app:packageDebug',原因是signingConfig未关联到buildType。

修正路径:
1. 打开app/build.gradle
2. 找到android { buildTypes { debug { ... } } }
3. 确保其中包含:
gradle debug { signingConfig signingConfigs.debug // 这一行必须存在 ... }
若缺失,手动添加。

完成这三处修正后,右键app模块 →Reload project,等待Sync完成。此时项目已具备编译条件。

4.4 功能验证:不是Run一下就完事,而是分层验证数据流

Run项目前,先做三层验证,确保数据链路畅通:

4.4.1 层级1:UI渲染验证(5秒)

点击AS工具栏Run 'app'(绿色三角形),选择真机或模拟器。App启动后:
- 主界面应显示默认城市“北京市”、默认天气“晴”、默认温度“23℃”
- 若显示“Hello World!”或一片空白,说明activity_main.xml未正确设置为setContentView(R.layout.activity_main),检查MainActivity.java第22行。

4.4.2 层级2:网络请求验证(30秒)

在主界面点击右上角“…” → “设置” → “API Key”,输入公开测试Key(如1234567890abcdef1234567890abcdef,项目已预置有效Key)。然后返回主界面,点击“定位”按钮。
- 打开AS底部Logcat,筛选器设为OkHttp
- 应看到类似日志:
--> GET http://api.openweathermap.org/data/2.5/weather?appid=1234567890abcdef1234567890abcdef&lat=39.9042&lon=116.4074
<-- 200 OK http://api.openweathermap.org/... (1247ms)
若看到<-- 401 Unauthorized,说明API Key无效,需重新在OpenWeather官网申请。

4.4.3 层级3:数据解析验证(2分钟)

在Logcat中筛选WeatherParser,触发一次定位后,应看到:
D/WeatherParser: Raw JSON: {"coord":{"lon":116.4074,"lat":39.9042},"weather":[{"main":"Clear","description":"clear sky"}],"main":{"temp":296.15,"feels_like":295.15,"temp_min":294.15,"temp_max":298.15,"pressure":1015,"humidity":65}}
D/WeatherParser: Parsed temp=23℃, humidity=65, weather=Clear

Parsed日志中temp0℃,说明Gson解析失败。此时打开WeatherParser.java,检查TypeAdapter"temp"字段的解析逻辑:

// 正确:处理开尔文转摄氏 double kelvin = jsonReader.nextDouble(); int celsius = (int) Math.round(kelvin - 273.15); weather.setTemp(celsius + "℃");

若学生误写为weather.setTemp((int) kelvin + "℃"),就会得到296℃这种荒谬结果。

完成这三层验证,你才算真正掌控了这个项目。它不再是一个黑盒APK,而是一条从用户点击、到网络穿梭、再到像素渲染的透明管道。

5. 常见问题与排查技巧实录:那些文档没写,但你一定会遇到的坑

即使严格按照教程操作,实战中仍有几个“必然发生”的问题。它们不出现在官方文档里,却高频出现在学生QQ群、论坛提问中。我把这些血泪经验整理成速查表,并附上独家排查技巧——有些方法,连AS官方文档都没提过。

5.1 真机调试:USB调试开了,AS还是找不到设备?

现象:手机开启“开发者选项”和“USB调试”,USB线连接电脑,AS设备列表为空,adb devices命令返回空。
原因:华为、小米、OPPO等国产手机需额外开启“USB调试(安全设置)”或“仅充电模式下允许ADB调试”。
独家技巧
- 华为手机:设置→系统和更新→开发者选项→启用“USB调试(安全设置)”(默认关闭)
- 小米手机:设置→我的设备→全部参数→连击“MIUI版本”7次→返回上一级→开发者选项→关闭“MIUI优化”(此开关会屏蔽ADB通信)
- 通用验证:在命令行执行adb kill-server && adb start-server,再adb devices。若仍无设备,拔插USB线时听电脑是否有“滴”声——无声说明USB握手失败,换线或换USB口。

5.2 城市搜索:输入“上海”没反应,Logcat无日志?

现象:在城市搜索框输入文字,键盘收起后无任何候选城市弹出,Logcat中SuggestionService无日志。
原因SuggestionService.java中Retrofit的Base URL被注释掉了。项目为防API Key泄露,将public static final String BASE_URL = "https://api.example.com/";设为// public static final String BASE_URL = "https://api.example.com/";,需手动取消注释。
排查技巧
- 在SuggestionService.java中搜索BASE_URL,确认是否被//注释
- 若已取消注释,检查app/src/main/AndroidManifest.xml中是否遗漏<uses-permission android:name="android.permission.INTERNET" />(此权限在<application>标签外,学生常误放在里面)

5.3 天气图标不显示:明明图片在drawable里,界面上却是空白?

现象:Logcat显示D/WeatherIcon: Set icon for Clear,但ImageView区域一片空白。
原因app/src/main/res/values/colors.xmlcolorPrimary被误改为#00000000(全透明),导致ImageViewandroid:tint="?attr/colorPrimary"失效,图标变透明。
独家技巧
- 在AS中按Ctrl+Shift+A(Windows)或Cmd+Shift+A(Mac),输入Find Action,搜索Edit Colors and Fonts
- 在Color Scheme → Android → Drawable中,临时将Default text color改为红色,重启AS。若图标变红,证明是tint问题,而非图片缺失。
- 修复:打开colors.xml,将<color name="colorPrimary">#6200EE</color>恢复为默认紫色。

5.4 Gradle Sync卡死:进度条停在99%,CPU风扇狂转?

现象:Sync长时间无响应,任务管理器显示java.exe占CPU 95%。
原因:AS的Gradle Daemon进程内存不足,默认仅分配512MB,而天气项目依赖较多(OkHttp、Gson、Support Library),需至少1GB。
独家技巧
- 关闭AS → 打开C:\Users\<用户名>\.gradle\gradle.properties(Windows)或~/.gradle/gradle.properties(Mac)
- 添加一行:
org.gradle.jvmargs=-Xmx1024m -XX:MaxMetaspaceSize=512m
- 重启AS,Sync速度提升3倍。

5.5 模拟器定位失败:Extended Controls发了坐标,App还是显示“定位中…”?

现象:在AS模拟器Extended Controls中设置经纬度,点击Send,但App无响应。
原因:模拟器系统时间与网络时间不同步,导致LocationManager认为定位数据过期(Android要求定位时间戳在当前时间±5分钟内)。
独家技巧
- 在模拟器中打开Settings → System → Date & time
- 关闭Use network-provided time,手动将日期设为今天,时间设为当前北京时间
- 返回Extended Controls,重新发送坐标,App立即刷新。

常见问题速查表

问题现象最可能原因快速验证命令修复方案
Run时提示Error: Could not find or load main class org.gradle.wrapper.GradleWrapperMaingradle/wrapper/gradle-wrapper.jar文件损坏ls -l gradle/wrapper/查看jar文件大小是否为0删除gradle/wrapper/目录,重新从AS导入项目
点击“定位”后Logcat显示java.lang.SecurityException: ... ACCESS_FINE_LOCATIONAndroidManifest.xml中权限声明位置错误grep -n "ACCESS_FINE_LOCATION" app/src/main/AndroidManifest.xml确认<uses-permission>标签在<application>外部
天气数据显示“–℃”,但Logcat有Parsed temp=23℃日志TextViewandroid:textColor被设为白色,背景也是白色在AS Layout Editor中选中TextView → 右侧Attributes面板查看textColor修改android:textColor="@android:color/black"
APK安装后图标显示为Android机器人,而非天气图标app/src/main/AndroidManifest.xmlandroid:icon指向错误grep "android:icon" app/src/main/AndroidManifest.xml确认值为@mipmap/ic_launcher,且app/src/main/res/mipmap-*/ic_launcher.png存在

这些问题,我在带毕设时平均每届学生都会遇到2-3个。它们不难,但缺乏指引时,足以让学生停滞一整天。这份实录,就是把那些“本该有人告诉你的事”,一次性说透。

6. 后续扩展与个性化改造:从复现到创造的跃迁路径

这个项目的价值,绝不仅限于“跑起来看看”。它是一块精心打磨的基石,你可以在上面安全地叠加自己的创意,而不用担心地基塌陷。下面我给出三条经过验证的扩展路径,每条都附带最小可行改动量预期效果,让你从使用者,变成创造者。

6.1 路径一:接入真实天气API(30分钟,零代码新增)

项目当前使用的是公开测试API(api.openweathermap.org),返回数据有限(如无空气质量、紫外线指数)。想展示更专业数据?只需替换API Key和Endpoint:

  1. 访问和风天气开发者平台,注册账号,创建应用,获取KEY
  2. 打开app/src/main/java/com/example/weather/WeatherApiManager.java
  3. private static final String BASE_URL = "http://api.openweathermap.org/data/2.5/";
    替换为private static final String BASE_URL = "https://dev.qweather.com/v7/weather/now?";
  4. 修改getWeatherByCoords方法中的URL拼接:
    java // 原:url = BASE_URL + "weather?appid=" + API_KEY + "&lat=" + lat + "&lon=" + lon; // 新: url = BASE_URL + "key=" + QWEATHER_KEY + "&location=" + lon + "," + lat;
  5. 更新WeatherParser.java中的JSON解析路径:
    java // 原:JsonObject data = root.getAsJsonObject("main"); // 新:JsonObject now = root.getAsJsonObject("now"); // String temp = now.get("temp").getAsString() + "℃";
    预期效果:主界面新增“体感温度”、“风力等级”、“能见度”字段,数据权威性提升一个量级。

6.2 路径二:增加7日天气预报(2小时,新增1个Activity)

当前只显示今日天气。想展示未来一周趋势?无需重写网络层,复用现有WeatherApiManager

  1. 创建新Activity:ForecastActivity.java,布局activity_forecast.xml(RecyclerView垂直列表)
  2. WeatherApiManager.java中新增方法:
    java public static void get7DayForecast(double lat, double lon, Callback callback) { String url = "https://dev.qweather.com/v7/weather/7d?key=" + KEY + "&location=" + lon + "," + lat; // 复用现有OkHttp请求逻辑 }
  3. ForecastActivity.java中调用,用Gson解析List<ForecastDay>,绑定到RecyclerView。
    关键技巧ForecastDay类中textDay字段对应白天天气描述,textNight对应夜间,tempMax/tempMin为高低温——这些字段名与和风API完全一致,无需TypeAdapter二次处理。
    预期效果:从主界面点击“7日预报”按钮,跳转新页面,显示未来七天日期、天气图标、最高/最低温折线图(用MPAndroidChart库,implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0')。

6.3 路径三:离线缓存增强(1小时,修改3个文件)

当前网络中断时,App只能显示上次数据。想实现“无网也能看昨天天气”?利用Android Room数据库:

  1. app/build.gradle中添加依赖:
    implementation "androidx.room:room-runtime:2.6.0"
    implementation "androidx.room:room-ktx:2.6.0"
  2. 创建WeatherDatabase.java(继承RoomDatabase),WeatherEntity.java(@Entity)
  3. 修改WeatherApiManager.java:请求成功后,插入WeatherEntity;请求失败时,从数据库查询最近一条记录。
    独家技巧:Room的@Insert(onConflict = OnConflictStrategy.REPLACE)可自动覆盖同城市同日期旧数据,避免手动判断。
    预期效果:飞行模式下打开App,仍能显示最后一次成功获取的天气数据,并标注“数据更新于:2023-10-25 14:30”。

这三条路径,没有一条要求你从零理解MVVM或Compose。它们都建立在现有代码的坚实基础上,用最少的新知识,撬动最大的功能增量。当你完成第一次扩展,那种“原来我也可以改出新东西”的笃定感,会彻底改变你对Android开发的认知——它不再是遥不可及的黑魔法,而是一套可以拆解、可以组合、可以生长的工具集。

我个人在实际带学生时发现,90%的毕业设计创新点,都来自这种“小步快跑”的扩展。与其花三个月纠结“要不要用Kotlin重写”,不如用两天时间,把空气质量指数加到界面上。后者能让你在答辩时指着真机说:“老师您看,这是北京今天的PM2.5,35微克/立方米,属于优。”——这句话带来的说服力,远胜于一百行炫技代码。

本文还有配套的精品资源,点击获取

简介:这个资源包提供一个功能完整的安卓天气预报应用,安装app-debug.apk就能在手机或模拟器上立刻查看实时天气、城市切换和定位效果。项目基于Android Studio开发,源码结构清晰,包含XML界面布局、Activity业务逻辑、OkHttp或Retrofit网络请求、Gson数据解析、LocationManager定位模块,以及天气图标、温度、湿度、风速等信息的展示逻辑。配套文档《基于Android天气预报系统设计与实现.docx》涵盖需求分析、技术选型依据、模块功能说明、程序流程图和关键代码片段;另一份《导入项目教程.docx》详细列出Android Studio中打开项目的每一步操作,包括Gradle版本匹配、SDK路径配置、JDK设置、签名文件处理及常见报错解决方案。所有配置文件齐全:build.gradle支持一键构建,settings.gradle适配多模块,proguard-rules.pro已预置混淆规则,gradle.properties含常用参数定义。整个工程无需额外改造即可编译运行,适合课程设计、毕业设计快速上手,也适合作为Android入门者练手的真实项目案例。


本文还有配套的精品资源,点击获取

http://www.rkmt.cn/news/1466177.html

相关文章:

  • wechat-need-web:突破微信网页版访问限制的终极解决方案
  • 2026年佛山公司官网怎么制作 - 凡科杰建云
  • 开源换脸软件FaceFusion安装教程
  • C++递推法(练习题)
  • springboot 增加消息自动重试机制 技术方案
  • ViGEmBus虚拟手柄驱动:5个步骤轻松实现Windows游戏控制器仿真
  • 别再只当编辑器用了!Jupyter Notebook的仪表盘(Dashboard)才是你的文件管理神器
  • 图片短信平台哪家靠谱?MMS多媒体方案供应商解析推荐 - Qqinqin
  • 用STM32CubeMX的DAC输出一个正弦波:从配置到代码的保姆级教程(基于HAL库)
  • 猫抓Cat-Catch浏览器资源嗅探扩展:5层架构设计与实战性能优化指南
  • PotPlayer字幕翻译插件完全指南:免费实时翻译外挂字幕终极方案
  • 2026义乌装修公司设计风格实力盘点|现代简约 / 新中式 / 轻奢奶油 / 意式极简 / 大平层 小户型全案落地|零增项无套路靠谱装修优选 - 企业品牌优选推荐官
  • 别再混淆灵敏度和响应度了!用NEP和最小可探测功率,手把手教你读懂光电探测器参数表
  • 实战指南:基于stm32f103c8t6原理图与快马平台快速构建物联网数据采集终端
  • 2026 韶关防水补漏三家品牌横向测评:厨卫屋面地下室修缮哪家靠谱?吉修匠 99.8 分五星稳居榜首 - 吉修匠
  • NCMconverter:专业级NCM音频格式解密与转换技术深度解析
  • 北京行业门户网站开发公司排行:资质与落地能力实测 - 奔跑123
  • PotPlayer百度翻译插件:3步实现外语字幕实时翻译的完整解决方案
  • 新手福音:用快马AI生成带详解的STM32 LED与按键实验代码,轻松入门嵌入式
  • 南宁二手奢侈品市场调研,热门款包包回收行情深度盘点 - 开心测评
  • 2026铝型材小件氧化选型评估:加工链路成熟度与供应商交付力指南 - 企师傅推荐官
  • 靠谱女装品牌加盟哪家好?免库存推荐,爱依莲四维实力全面解析 - 资讯纵览
  • MATLAB车载网络仿真工具包:含自定义车辆移动模型与全流程操作录像
  • 师大中高教育联系电话整理:正规办学实力护航 高考升学更省心 - GEO代运营aigeo678
  • 爬虫老手教你:除了换IP和加延迟,搞定requests的Max retries exceeded还有这些招(含Session实战)
  • 印度AI落地困境:从实验场到共同创造者的四重技术关卡
  • 微信投票功能使用指南:如何轻松发起投票?|火星投票2026防刷零广告教程 - 微信投票小程序
  • 2026高强度耐磨浇注料厂家选型观察:供应商交付力与场景适配度评估指南 - 企师傅推荐官
  • 告别繁琐操作:用快马AI快速生成图像处理创意原型
  • 多组学生物衰老时钟!高精度、可解释、可扩展