ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Android天气预报课设源码实战:从环境配置到二次开发全指南

Android天气预报课设源码实战:从环境配置到二次开发全指南 简介这份资源是面向Android初学者与课程设计需求者的完整天气预报App项目源码基于Android Studio开发可直接导入运行适合作为移动开发课程的期末大作业或练手项目。项目通过中国天气网API以HTTP方式获取网络数据使用JSON解析后展示到界面并借助数据库存储城市及其对应URL实现城市收藏与多城市天气切换功能。压缩包共107个文件约6.75MB其中包含53个png图片资源、24个xml布局与配置、15个java核心代码文件以及gradle构建脚本、jar依赖库等结构完整、层次清晰。目前已有532人学习下载。读者可从中掌握网络请求、JSON解析、SQLite数据库操作与界面联动等关键技能并直接获得一套可运行、可参考的课设方案便于快速理解项目架构与实现思路。1. 从一份天气预报课设源码说起Android Studio 项目怎么跑起来、怎么改、怎么讲清楚每年期末总有一批人对着「Android Studio实现天气预报App满分课设大作业项目源码.zip」这类压缩包发愁。解压之后目录一堆gradle、app、build.gradle、settings.gradle全在但双击哪个文件、用什么版本打开、为什么一编译就红一片没人告诉你。这篇不是泛泛而谈的科普而是把一份典型的 Android 天气预报课设源码从环境配置、项目导入、接口替换、界面改造到答辩演示完整走一遍。适合两类人一是第一次接触 Android Studio 开发 App 项目、需要交课设的学生二是想拿一份现成源码做二次开发、但被 Gradle 版本和 SDK 路径卡住的开发者。核心结论先放这里这类项目能不能跑起来八成取决于 Gradle 与 AGP 版本是否匹配、SDK 是否补齐、以及天气接口是否还有效代码本身反而最简单。2. 环境准备Android Studio 安装配置与项目导入的完整路径2.1 版本选择为什么不要盲目追新Android Studio 的版本迭代很快从 Dolphin 2021.3.1 到后来的 Hedgehog、Iguana每个大版本对 Gradle 和 AGP 的最低要求都不一样。课设源码通常是在某个特定版本下写的如果你用最新版打开一个两三年前的工程大概率会遇到Unsupported class file major version或者Could not find method implementation()这类报错。我一般的做法是先看源码根目录的build.gradle项目级找到com.android.tools.build:gradle的版本号再反推需要哪个 Android Studio。比如// 项目级 build.gradle buildscript { dependencies { classpath com.android.tools.build:gradle:7.0.4 // AGP 版本 } }AGP 7.0.4 对应 Gradle 7.0.2 以上对应 Android Studio Arctic Fox 2020.3.1 以上。如果你装的是 Dolphin 2021.3.1完全兼容。但如果你装了最新版它自带的 Gradle 可能是 8.x直接打开会提示升级 AGP升完之后代码里的compile要改成implementationandroid.enableR8要删掉一堆连锁反应。提示课设项目优先用源码指定的版本不要手贱点「Upgrade」。升级容易回退难。安装 Android Studio 时SDK 路径建议不要放在 C 盘默认位置改到 D 盘或 E 盘比如D:\Android\Sdk。原因很简单一个完整的 SDK 加上模拟器镜像轻松超过 20GBC 盘红了会影响 Gradle 编译速度。安装向导里勾选 SDK Platforms 时至少勾上Android 11.0 (R)和Android 13.0 (T)前者兼容大多数课设源码的compileSdkVersion后者用于真机调试。2.2 导入项目从 zip 到可编译状态拿到压缩包后不要直接双击.zip里的文件。先解压到一个纯英文、无空格的路径比如D:\Projects\WeatherApp。路径里有中文或空格Gradle 在 Windows 上会报Failed to parse XML或者Could not resolve之类的玄学错误。打开 Android Studio选择Open定位到解压后的根目录注意是包含settings.gradle的那一层不是app目录。点 OK 之后IDE 会开始 Gradle Sync。这时候看底部进度条如果卡在Download gradle-7.x-bin.zip很久说明它在从国外源下载 Gradle 发行包。# 手动下载 Gradle 并放到缓存目录Windows # 查看项目需要的 Gradle 版本 cat gradle/wrapper/gradle-wrapper.properties # 输出示例 # distributionUrlhttps\://services.gradle.org/distributions/gradle-7.0.2-bin.zip看到版本号后可以手动下载对应的gradle-7.0.2-bin.zip放到C:\Users\你的用户名\.gradle\wrapper\dists\gradle-7.0.2-bin\下的随机字符串目录里重启 Sync。这一步能省掉大量等待时间。Sync 成功后如果app模块的代码还是红的检查local.properties文件是否存在内容是否指向正确的 SDK 路径# local.properties sdk.dirD\:\\Android\\Sdk注意 Windows 下路径的反斜杠要转义或者直接用正斜杠D:/Android/Sdk。这个文件通常被.gitignore忽略所以从别人那里拷来的项目往往没有需要自己建。2.3 模拟器与真机怎么选更省事课设答辩通常需要现场演示模拟器启动慢、占内存而且天气 App 往往要定位模拟器的 GPS 是模拟的容易出偏差。我建议用真机调试打开手机开发者选项开启 USB 调试用数据线连电脑。Android Studio 顶部设备列表里会出现你的手机型号点运行直接安装。如果非要用模拟器创建 AVD 时选Pixel 5或Pixel 6系统镜像选API 30或API 31不要选带 Google Play 的版本那个镜像更大更慢。创建完成后在 AVD 设置里把Graphics改成Hardware - GLES 2.0启动速度会快不少。3. 源码结构拆解天气预报 App 的核心模块与数据流3.1 目录结构哪些文件必须改哪些可以不动一份典型的天气预报课设源码目录结构大致如下WeatherApp/ ├── app/ │ ├── src/main/ │ │ ├── java/com/example/weather/ │ │ │ ├── MainActivity.java # 主界面 │ │ │ ├── WeatherActivity.java # 天气详情页 │ │ │ ├── adapter/ # 列表适配器 │ │ │ ├── db/ # 数据库操作 │ │ │ ├── model/ # 数据实体类 │ │ │ └── util/ # 网络请求、工具类 │ │ ├── res/ │ │ │ ├── layout/ # 布局文件 │ │ │ ├── drawable/ # 图片资源 │ │ │ └── values/ # 颜色、字符串、样式 │ │ └── AndroidManifest.xml # 权限与 Activity 注册 │ └── build.gradle # 模块级配置 ├── build.gradle # 项目级配置 ├── settings.gradle └── gradle/wrapper/必须改的文件其实不多AndroidManifest.xml里的网络权限和定位权限、util目录下的 API 请求地址、model里的数据字段如果接口返回结构变了。可以不动的是布局文件、适配器逻辑、数据库表结构这些是课设的「骨架」改了反而容易出错。3.2 网络请求模块从和风天气到任意接口的替换大多数天气预报课设用的是和风天气、心知天气或者 OpenWeatherMap 的免费接口。这些接口有个共同点需要注册账号拿 Key而且免费版有调用次数限制。源码里通常会把 Key 硬编码在一个Constant.java或HttpUtil.java里。// util/Constant.java public class Constant { // 原作者的 Key大概率已失效 public static final String WEATHER_KEY xxxxxxxxxxxxxxxx; public static final String WEATHER_URL https://devapi.qweather.com/v7/weather/now; }你要做的是去对应平台注册自己的账号拿到新 Key替换掉这一行。注意和风天气的免费版现在需要绑定域名或 IP个人开发者用localhost或127.0.0.1通常不行得用真实域名或者申请开发者认证。如果嫌麻烦可以换成 OpenWeatherMap注册简单免费额度够课设用。替换完 Key 之后还要检查请求参数。比如和风天气的now接口需要location参数格式是经度,纬度而源码里可能写的是城市名。这时候要么改代码把城市名转成经纬度要么换用city参数部分接口支持。// util/HttpUtil.java 片段 public static String getWeather(String city) { // 原代码可能直接拼 city String url Constant.WEATHER_URL ?location city key Constant.WEATHER_KEY; // 如果接口要求经纬度这里需要先调用地理编码接口 return HttpUtils.get(url); }逻辑说明getWeather方法负责拼接完整 URL 并发起 GET 请求。参数city是用户输入或定位得到的城市名。如果接口不支持城市名需要先调用地理编码接口把城市名转成locationId或经纬度。这一步是课设源码最容易翻车的地方因为原作者可能用的是旧版接口新版接口参数变了但代码没更新。3.3 数据解析与 UI 绑定JSON 到界面的最后一公里接口返回的 JSON 结构决定了model类怎么写。以和风天气now接口为例返回格式大致是{ code: 200, now: { temp: 25, text: 晴, humidity: 40, windDir: 西北风 } }对应的 Java 实体类// model/WeatherNow.java public class WeatherNow { private String temp; private String text; private String humidity; private String windDir; // getter 和 setter 省略 }解析时用 Gson 或 FastJson// WeatherActivity.java 片段 Gson gson new Gson(); WeatherResponse response gson.fromJson(jsonString, WeatherResponse.class); if (200.equals(response.getCode())) { WeatherNow now response.getNow(); tvTemp.setText(now.getTemp() ℃); tvText.setText(now.getText()); tvHumidity.setText(湿度 now.getHumidity() %); }参数说明jsonString是网络请求返回的原始字符串WeatherResponse是顶层实体类包含code和now两个字段tvTemp、tvText等是布局文件里定义的 TextView。如果解析后界面没变化先打 Log 看jsonString是否为空再检查字段名是否和 JSON 里的 key 完全一致大小写敏感。4. 避坑与排查课设源码跑不起来时先看这五条4.1 现象Gradle Sync 失败报Could not find com.android.tools.build:gradle:x.x.x原因项目级build.gradle里指定的 AGP 版本在 Google Maven 仓库里不存在或者网络无法访问dl.google.com。解决打开项目级build.gradle把classpath改成你本地已有的 AGP 版本。如果不确定可以在 Android Studio 安装目录的gradle/m2repository/com/android/tools/build/gradle/下看有哪些版本。改完后在settings.gradle里确保google()和mavenCentral()都在repositories块中。4.2 现象编译通过但运行闪退Logcat 报java.lang.SecurityException: Permission denied原因AndroidManifest.xml里缺少网络权限或定位权限或者 Android 6.0 以上没有动态申请权限。解决在AndroidManifest.xml的manifest标签下添加uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_FINE_LOCATION / uses-permission android:nameandroid.permission.ACCESS_COARSE_LOCATION /然后在MainActivity的onCreate里加动态申请if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) ! PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1); }4.3 现象天气数据不显示Logcat 里 URL 请求返回code: 401或code: 403原因API Key 无效、过期或者请求参数不完整。和风天气的401通常表示 Key 错误403表示 Key 没有访问该接口的权限。解决登录天气平台控制台确认 Key 状态和剩余调用次数。如果是新注册的 Key检查是否需要在请求头里加X-QW-Api-Key而不是放在 URL 参数里。部分平台对免费版有 IP 白名单限制本地调试时把127.0.0.1加进去。4.4 现象模拟器里定位失败天气一直显示「定位中」原因模拟器默认没有 GPS 信号或者没有在 AVD 设置里配置虚拟位置。解决打开模拟器的Extended Controls找到Location选项卡手动输入经纬度比如北京39.9042, 116.4074点Send。然后在代码里检查LocationManager是否正常返回。如果用的是高德或百度定位 SDK还需要在AndroidManifest.xml里配置对应的 AppKey。4.5 现象真机安装成功但打开后白屏没有任何报错原因MainActivity的布局文件里根布局设置了android:visibilitygone或者setContentView引用的布局 ID 不对。解决打开res/layout/activity_main.xml检查根布局的visibility属性确保是visible。然后回到MainActivity.java确认setContentView(R.layout.activity_main)里的布局名和文件名一致。如果用的是 ViewBinding 或 DataBinding检查build.gradle里是否开启了对应开关。5. 二次开发与答辩加分把课设改成能讲出亮点的作品5.1 界面改造用 ConstraintLayout 替换 LinearLayout 嵌套原源码的布局往往是LinearLayout一层套一层改起来费劲性能也差。我一般会保留原有控件 ID把根布局换成ConstraintLayout用约束关系重新排布。这样在答辩时可以说「优化了布局层级减少了过度绘制」比单纯说「我改了颜色」有说服力。!-- 改造后的 activity_main.xml 片段 -- androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:apphttp://schemas.android.com/apk/res-auto android:layout_widthmatch_parent android:layout_heightmatch_parent TextView android:idid/tv_city android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintTop_toTopOfparent app:layout_constraintStart_toStartOfparent app:layout_constraintEnd_toEndOfparent android:layout_marginTop32dp android:textSize24sp / TextView android:idid/tv_temp android:layout_widthwrap_content android:layout_heightwrap_content app:layout_constraintTop_toBottomOfid/tv_city app:layout_constraintStart_toStartOfparent app:layout_constraintEnd_toEndOfparent android:textSize64sp / /androidx.constraintlayout.widget.ConstraintLayout参数说明app:layout_constraintTop_toTopOfparent表示顶部对齐父容器app:layout_constraintStart_toStartOf和app:layout_constraintEnd_toEndOf配合使用可以让控件水平居中。android:layout_marginTop控制间距。改造后布局层级从原来的三四层降到一层渲染速度肉眼可见地变快。5.2 数据缓存用 Room 替代 SQLiteOpenHelper原源码如果用的是SQLiteOpenHelper手写 SQL可以改成 Room。Room 是 Jetpack 组件代码更简洁答辩时也能体现你对现代 Android 开发技术的了解。// db/WeatherDatabase.java Database(entities {WeatherEntity.class}, version 1, exportSchema false) public abstract class WeatherDatabase extends RoomDatabase { private static volatile WeatherDatabase INSTANCE; public abstract WeatherDao weatherDao(); public static WeatherDatabase getInstance(Context context) { if (INSTANCE null) { synchronized (WeatherDatabase.class) { if (INSTANCE null) { INSTANCE Room.databaseBuilder(context.getApplicationContext(), WeatherDatabase.class, weather_db) .build(); } } } return INSTANCE; } }逻辑说明Database注解声明数据库版本和实体类weatherDao()是抽象方法Room 会自动生成实现getInstance用双重检查锁保证单例。相比SQLiteOpenHelperRoom 在编译期就能检查 SQL 语法错误减少运行时崩溃。5.3 答辩演示三个能加分的细节第一准备两套数据源。演示时先用真实接口如果网络卡顿立刻切换到本地 Mock 数据保证界面不空。Mock 数据可以放在assets目录下用Gson读取。第二在README.md里写清楚项目结构、用到的技术栈、接口来源和运行步骤。答辩老师翻代码时有文档的项目印象分更高。第三录一段 30 秒的屏幕录制展示从启动到定位、请求、展示的完整流程。万一现场设备出问题直接放视频不至于冷场。5.4 一个我踩过的坑onBackPressed无效有次改一个课设发现按返回键没反应。查了半天原因是MainActivity继承的是AppCompatActivity但源码里重写了onBackPressed方法却没有调用super.onBackPressed()而且方法签名写成了onBackPressed(int)。正确写法Override public void onBackPressed() { if (webView.canGoBack()) { webView.goBack(); } else { super.onBackPressed(); } }注意方法没有参数且必须调用super才能让系统执行默认返回逻辑。这个坑在热词里也出现过说明不少人遇到过。5.5 最后的习惯先跑通再优化别反过来我带过几届课设发现一个规律一上来就想着换架构、加动画、接第三方 SDK 的人往往到截止日期还在调 Gradle。反而是那些先把原源码跑通、再逐个模块替换的人最后交出来的东西更完整。我的习惯是拿到任何一份源码先不改一行代码确保它能编译、能运行、能看到界面。然后再动第一个文件。这个顺序看起来慢其实是唯一的后悔药。希望帮到你。本文还有配套的精品资源点击获取
返回列表