说实话,这段时间帮几个学弟学妹把控计算机毕业设计,我连续撞上了同一个高分方向——SpringBoot+Android的宠物领养APP。乍一看这题目挺"常规":一个后端写接口,一个客户端调接口,再套上前后端分离架构的名头,好像就能交差了。可真上手去做才发现,从"流浪动物救助与领养"的业务建模,到移动端的网络调试、状态流转、图片存取,坑远比想象中多。特别是"寻主"和"领养"这两类场景在数据模型上要怎么统一,很多文章都没讲透。
这篇文章我想把整个"基于SpringBoot与Android的移动端宠物寻主与领养系统"从设计到落地的完整链路拆开聊一聊。里面会包含我实际带队做这个项目时的分层思路、核心表结构、接口约定、Android客户端封装方式,以及一批只有真正跑过联调才会踩到的坑。无论你是准备拿它当毕业设计、课设,还是单纯想做一个练手项目,这篇文章应该能帮你少走至少一周的弯路。
做完整个项目你再回头看,会觉得这个题目的价值不在"新技术"上,而在于它逼迫你把一个完整的业务闭环真正跑通:用户注册登录、发布宠物、浏览筛选、提交领养申请、审核状态流转、走失与拾获登记、认领匹配——每一环都藏在前后端配合的细节里。
1. 先把需求看清:宠物领养不是普通"增删改查"
1.1 场景拆解:救助、领养、寻主到底包含哪些业务
很多同学拿到这个题目第一反应是"不就是发布宠物 + 列表展示 + 申请领养嘛",结果做完一轮就被老师问住了——流浪动物救助和宠物寻主根本不是同一个玩法。
我习惯把这个系统拆成三类核心场景:
第一类是流浪动物救助与领养。流浪动物被救助后,救助人需要登记宠物基本信息(品种、年龄、毛色、健康状况、是否绝育、疫苗情况),上传照片,设置领养条件(如"仅限本地""需接受回访"),然后等普通用户来提交领养申请。救助人或管理员审核申请,通过后双方线下见面、完成送养,系统里还要记录领养状态。
第二类是宠物寻主。这里面又分两种子场景:一种是用户自己的宠物走失了,用户发布"寻主启事"(其实就是寻宠物),写明特征、走失地点、时间、酬谢方式;另一种是用户在外面捡到了疑似走失的宠物,发布"拾获登记",留照片、留拾获位置。系统需要支持这两种信息之间按品种、颜色、地区做模糊匹配,把可能相关的走失和拾获信息相互推荐。
第三类是平台基础能力。用户注册登录、个人信息管理、收藏、浏览记录、领养申请进度查询、系统消息通知,还有最容易被忽略的管理后台——管理员需要能审核宠物发布内容、管理用户、下架违规宠物信息。
想清楚这三层,你才能回答"这个系统的核心创新点是什么"。如果只做一套普通的CRUD,答辩时连第二个问题都撑不过去。
1.2 为什么是 SpringBoot + Android + 前后端分离
这个组合,说句实话,是毕业设计里"稳妥性与工作量"平衡得最好的方案之一。
SpringBoot后端选型的理由很实在:它内置Tomcat、自动配置、生态成熟,MyBatis-Plus 或者 Spring Data JPA 可以省掉大量单表CRUD代码。对于一个以业务逻辑和流程为主的系统,SpringBoot 能让你把精力放在"流程怎么走"而不是"框架怎么配"上。而且答辩时老师对这个技术栈的接受度很高,不会被追问太多冷门问题。
Android原生客户端选Java/Kotlin是因为移动端的独立性。这个题目明确要求做APP,那就用原生来实现,配合RecyclerView、Retrofit、Glide这几个库就足够完成信息流、图片加载和网络请求。
前后端分离架构在这里不是噱头,而是有实际意义的:后端只提供RESTful API,Android端通过HTTP/HTTPS调用,两边可以并行开发、单独测试。这个架构还能顺带导出接口文档(比如用knife4j或springdoc),答辩时展示分工界面会非常好看。
1.3 角色与模块划分:分清"谁"在用什么功能
项目里我建议至少设计三种角色:普通用户、救助/送养人(可并入普通用户升级权限)、管理员。为了简单,也可以采用"普通用户 + 管理员"双角色,让普通用户同时拥有"发布走失""发布拾获""提交领养申请"的权限,管理员负责审核和数据管理。
模块上这样分:
- 用户模块:注册、登录、找回密码、个人资料、我的发布、我的申请
- 宠物模块:宠物信息发布、宠物列表(按品种/地区/状态筛选)、宠物详情、图片轮播
- 领养模块:提交领养申请、审核申请、领养状态流转(待审核→已通过/已拒绝→确认领养→完成)
- 寻主模块:走失信息发布、拾获信息登记、智能匹配推荐、认领确认
- 救助模块:救助记录登记(救助人、时间、地点、救助经过、医疗处理情况)
- 消息模块:申请审核结果通知、匹配成功提醒
这样划分以后,前后端的接口边界就非常清晰了。后端按模块建包建表,Android端按模块建页面,哪怕两个人协作,也不会互相等着。
2. 后端:SpringBoot 这样做,既稳又好答辩
2.1 分层结构是最容易被低估的得分点
后端结构我推荐这样做,基本是行业里最常见的规范:
com.example.petadoption ├── controller # 接口层,只做参数接收与响应包装 ├── service # 业务层,核心逻辑与事务 ├── mapper # 数据访问层(MyBatis-Plus 的 Mapper) ├── entity # 实体类 ├── dto # 请求/响应对象,不要直接用实体接收参数 ├── common # 统一返回结果、全局异常处理、常量 ├── config # 配置类(跨域、拦截器、静态资源映射) ├── utils # JWT工具、文件上传工具、时间工具 └── PetApplication.java这里要特别强调一点:接口入参不要直接用Entity。很多同学图省事,让Controller直接接收Entity对象,结果前端传什么都能往数据库里塞,状态字段、用户ID都能被客户端篡改。正确的做法是定义PetPublishDto、AdoptionApplyDto这类DTO,只接收业务需要的字段,service层再转成Entity保存。这不仅安全,答辩时也是加分点,老师一眼就看出你懂分层。
2.2 核心数据表设计:一张表一个关注点
表的设计决定了整个项目的表达能力。我按模块整理了一份核心表清单,字段我只挑关键的讲:
| 表名 | 核心字段 | 状态字段设计 |
|---|---|---|
| user | id、phone、password、nickname、avatar、role | role:0普通 1管理员 |
| pet | id、user_id、name、category、breed、gender、age、color、health、vaccine、address、description、images、status | status:0待审核 1展示中 2已领养 3已下架 |
| adoption_application | id、pet_id、user_id、apply_reason、contact_phone、contact_address、status、create_time | status:0待审核 1已通过 2已拒绝 3已取消 4已完成 |
| lost_report | id、user_id、pet_name、category、breed、color、lost_address、lost_time、feature、reward、contact、images、status | status:0寻宠中 1已找到 |
| found_report | id、user_id、category、breed、color、found_address、found_time、feature、contact、images、status | status:0待认领 1已认领 |
| rescue_record | id、user_id、pet_id、rescue_address、rescue_time、medical_desc、remark | 关联宠物与救助记录 |
几个设计上的细节我要单独说:
- 状态字段一律用数字或字符串枚举,不要直接存"已领养"这种中文。否则后面你要统计"领养转化率""各状态下宠物数量"时,SQL 会写到怀疑人生。用数字 + 常量类或枚举类,前端再映射成文案展示。
images字段可以存逗号分隔的URL字符串,因为一个宠物最多上传3~5张图,没必要单独建一张图片表。但如果做管理后台要大量查询,也可以规范化为 pet_image 子表,这个看工作量取舍。- 所有表保留
create_time和update_time,用 MyBatis-Plus 的自动填充,减少重复代码。 adoption_application要加pet_id和user_id的联合唯一索引吗?我建议加,但要注意业务允许不允许同一个人反复申请同一只宠物。明确"一个用户只能申请一次,失败后可再次申请"时,前端在提交前就做校验,后端也得兜底。
2.3 登录认证:JWT 方案如何落地
毕业设计级别用JWT最合适,无状态、不需要在服务端存Session、Android端存好token每次请求塞到Header里就行。
具体做法:
- 用户登录时后端校验手机号+密码,生成JWT返回,payload里放
userId、role,设置过期时间(我一般设7天,毕业设计演示够用)。 - 定义一个拦截器
AuthInterceptor,拦截除了login、register、宠物列表等公开接口以外的路径。从请求头Authorization取 token,解析失败抛401,解析成功把 userId 放进ThreadLocal或请求上下文。 - Android 端在
OkHttp的Interceptor里统一往请求头塞 token,这样所有请求都无需单独处理认证。
密码存储方面,别用明文。最简单可靠的是BCrypt加密,Spring Security 的BCryptPasswordEncoder可以单独拿出来用,不引整个Security也行。
2.4 图片上传与静态资源映射:细节决定演示效果
宠物领养APP里图片是灵魂,但图片这块往往坑最多。
后端建议本地上传+静态资源映射的方案。在application.yml里配:
spring: servlet: multipart: max-file-size: 10MB max-request-size: 20MB custom: upload-path: ./upload/再写一个上传工具类,用UUID重命名文件避免中文和重名问题,按日期分目录存储,然后返回可访问的URL。关键是要加一个WebMvcConfigurer配置类,把本地磁盘路径映射为URL:
@Configuration public class WebConfig implements WebMvcConfigurer { @Value("${custom.upload-path}") private String uploadPath; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceResolver(new PathResourceResolver()) .addResourceLocations("file:" + uploadPath); } }这里有个实战教训:路径拼接里的file:前缀必须带,Windows 和 Linux 下路径分隔符不一样,所以最好的方式是后端提供一个FileUtils.getAbsolutePath()方法统一处理。还有,返回给Android端的图片URL一定要用完整路径(IP+端口+路径),不能只给/upload/xxx.jpg。
3. Android端:代码别全塞进Activity,架构先立起来
3.1 客户端架构:MVVM 是省心之选
Android 端如果不用架构,最后所有逻辑都会堆进Activity,一到联调阶段就炸——回调嵌套混乱、状态不同步、一个页面几百行。我建议直接用MVVM,也就是ViewModel + LiveData + Repository这套组合。
Android Studio 里建议创建项目时选 Java(稳妥,资料多)或 Kotlin(更现代)。这个项目客户端重点模块就这几个:
网络层:Retrofit + OkHttp + Gson/GsonConverter图片加载:Glide页面:RecyclerView + CardView + SmartRefreshLayout(做下拉刷新/加载更多)数据库:如果需要本地收藏,用 Room;否则 SharedPreferences 存 token 就够了
3.2 网络层封装:统一 BaseUrl、统一返回体、统一异常
客户端网络层是整个APP的命脉,我一般这样封装:
- 定义一个
ApiResult<T>类,字段和后端统一返回体对齐:code、message、data。 - 用
Retrofit.Builder().baseUrl(BASE_URL)创建接口代理。BASE_URL 这里是个大坑,见下一条。 OkHttp添加两个拦截器:一个AuthInterceptor(塞token),一个LoggingInterceptor(打印日志,联调必备)。- 定义一个
NetworkCallback包装retrofit2.Callback,在onFailure里统一处理网络异常,Toast 提示"网络连接失败";onResponse里解析code,code=401时跳转登录页,其他code直接抛业务错误。
BASE_URL 的选择:Android 模拟器里访问宿主机要用http://10.0.2.2:8080/,真机要用http://<电脑局域网IP>:8080/。不能用localhost,因为手机上的 localhost 指的是手机自己。这个错误几乎每个新手都会犯。
3.3 核心页面与交互流程
客户端页面我按主线整理几个关键实现点:
- 首页:
RecyclerView展示宠物卡片,卡片上显示宠物封面图、名称、品种、状态标签(待领养/已领养)。用SmartRefreshLayout实现分页加载,下拉刷新列表。 - 宠物详情页:顶部用
ViewPager2做图片轮播,下方展示基本信息、健康描述、救助故事。根据pet.status判断按钮是"申请领养"还是"已领养"。这里要注意,已登录用户才能点申请领养,未登录要跳转登录页。 - 发布宠物页:表单 + 图片选择。图片选择用系统相册或相机,拿到
Uri后先压缩再上传,上传走独立的接口,成功后把返回的图片URL作为表单字段提交。 - 寻主匹配页:输入走失/拾获信息后,后端返回可能匹配的宠物列表,客户端用列表展示,给每条匹配记录提供"联系TA"按钮。
3.4 Glide 加载图片与 Android 明文HTTP配置
Glide 的使用很简单:
Glide.with(context) .load(pet.getImages().get(0)) .placeholder(R.drawable.ic_placeholder) .error(R.drawable.ic_error) .into(imageView);但有两个必须提前处理的点:
第一,AndroidManifest.xml要声明网络权限<uses-permission android:name="android.permission.INTERNET"/>。第二,如果后端接口是http://明文,Android 9(API 28)开始默认禁止明文流量。最简单的处理办法是在<application>标签上加android:usesCleartextTraffic="true"。如果项目将来要上架,建议用networkSecurityConfig精确允许指定域名明文,但做课设毕设直接用前者就好,省事。
4. 前后端联调:接口规范定了,事情就成了一半
4.1 接口约定:RESTful + 统一返回体 + 分页参数
前后端分离的核心是接口约定。我定义一个统一返回体,后端所有接口都这么返回:
{ "code": 200, "message": "success", "data": { } }code=200表示成功,400表示参数错误,401表示未登录或token过期,500表示服务器异常。Android端拿到code后统一处理,业务逻辑集中在data里。
接口按REST风格设计,我列几个核心接口作为参考:
| 功能 | 接口 | 方法 | 说明 |
|---|---|---|---|
| 用户注册 | /api/user/register | POST | 手机号、密码、验证码 |
| 用户登录 | /api/user/login | POST | 返回token和用户信息 |
| 宠物列表 | /api/pet/list | GET | 分页、按品种/状态筛选 |
| 发布宠物 | /api/pet/publish | POST | 表单+图片URL数组 |
| 宠物详情 | /api/pet/{id} | GET | 图片、状态、救助记录 |
| 提交领养申请 | /api/adoption/apply | POST | petId、申请理由、联系方式 |
| 查询我的申请 | /api/adoption/my | GET | 我的申请列表 |
| 审核申请 | /api/adoption/review | POST | 申请id、通过/拒绝、审核备注 |
| 发布走失信息 | /api/lost/publish | POST | 走失宠物信息 |
| 发布拾获信息 | /api/found/publish | POST | 拾获宠物信息 |
| 寻主匹配 | /api/match/search | GET | 按品种/颜色/地区匹配 |
分页参数统一叫pageNum和pageSize,返回体里 data 包两个字段:total和list。Android端根据total > currentSize判断是否还有下一页。
4.2 联调阶段最崩溃的几个问题
联调阶段我几乎每次都会遇到,全部记录下来:
- 模拟器访问不到后端:宿主机用
10.0.2.2代替localhost,这是Android模拟器的固定约定。如果还不行,检查后端是否启动在0.0.0.0而不是127.0.0.1。 - 真机访问不到后端:手机和电脑必须连同一个WiFi,后端启动后电脑防火墙要放行8080端口。Windows 下经常需要手动添加入站规则,或者临时关防火墙测试。
- HTTP 明文被拦截:上一条说的
usesCleartextTraffic。 - 端口被占用:SpringBoot 的8080被其他程序占了,启动直接报错。改端口用
server.port=8081,改完Android端的BASE_URL也要同步改。 - 时间格式解析不了:后端返回
LocalDateTime序列化成"2025-01-16T10:20:30",Gson 解析可能失败。统一在Spring里配置Jackson格式:spring.jackson.date-format=yyyy-MM-dd HH:mm:ss,同时在Android端给时间字段加@SerializedName和自定义解析器,或者后端直接把时间转好字符串再返回。
4.3 跨域问题要不要处理
原生Android App 其实不涉及浏览器同源策略,所以联调时不会出现跨域问题。但有两个例外:如果你在客户端用了WebView加载管理页面,或者后端将来要支持Web管理端,那么CorsConfig还是要配。我建议顺手配一个全局跨域,成本极低。
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }5. 核心模块实现复盘:从发布到领养的完整链路
5.1 宠物发布到首页列表:一条让人头秃却又最简单的链路
先说最简单的链路:发布宠物 → 首页展示。
Android端流程:用户填写宠物表单 → 选择图片 → 图片先上传到/api/upload/image→ 后端返回图片URL → 表单连同图片URL数组一起提交到/api/pet/publish→ 后端校验登录状态和参数 → 保存pet记录,status置为0(待审核)→ 返回发布成功。
这里有两个细节:
第一,图片上传和宠物信息提交是两步。图片上传接口在用户还没填写完表单时就可以先调,这样体验更好,也避免了一张大图卡住整个表单提交。我一般会在onActivityResult拿到图片后立即调上传接口,然后把返回URL先积累到一个列表,提交表单时一次性带上。
第二,管理员审核逻辑。宠物发布后status=0,首页列表查询只查status=1(展示中)。这就在前端体现为"我发布了但是首页看不到",需要做"我的发布"页面查看自己的宠物审核状态。这个流程至少会有用户、管理员两端的操作,演示起来内容也丰富。
首页列表后端Service层大致逻辑:
public PageResult<PetVO> getPetList(int pageNum, int pageSize, String category, String city) { LambdaQueryWrapper<Pet> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Pet::getStatus, 1) .eq(StringUtils.isNotBlank(category), Pet::getCategory, category) .eq(StringUtils.isNotBlank(city), Pet::getCity, city) .orderByDesc(Pet::getCreateTime); Page<Pet> page = petMapper.selectPage(new Page<>(pageNum, pageSize), wrapper); // 转 VO,把 images 逗号字符串拆成 List<String> }5.2 领养申请状态机:用一张表表达完整流程
领养申请是整个项目业务逻辑最核心、最值得在答辩时展开讲的部分。它的状态流转是这样的:
用户提交申请(status=0 待审核) ├─ 管理员/救助人通过(status=1 已通过)→ 用户确认领养(status=4 已完成) ├─ 管理员/救助人拒绝(status=2 已拒绝) └─ 用户自己取消(status=3 已取消)Android端在"我的申请"里,根据status显示不同按钮和文案:待审核显示"审核中"标签;已通过显示"确认领养"和"联系送养人";已完成显示"领养完成";已拒绝显示"被拒绝"。
后端在提交申请时要多做三件事:
- 校验宠物状态必须为1(展示中),否则直接返回"该宠物不可申请"。
- 校验当前用户不是宠物发布者本人,自己的宠物不能申请领养。
- 防重复提交:同一个人对同一只宠物只能有一条
status IN (0,1)的记录,否则就提示"您已申请过该宠物"。
第3点非常重要,我见过很多项目在这里没拦住,导致用户疯狂点了十几次申请,列表里全是重复记录。
5.3 寻主与拾获匹配:这个功能最能体现设计能力
寻主部分要让功能看起来"智能化",其实关键就在匹配算法。我的实现思路是:
- 用户发布走失信息时填
category(猫/狗)、breed(品种)、color(毛色)、lost_address(走失城市)。 - 用户发布拾获信息时填同样的字段。
- 匹配接口
/api/match/search接受一个参数——到底是找"疑似我走失的宠物",还是"疑似这只走失宠物的拾获信息"。后端用Java 8 Stream 或SQL做模糊匹配,匹配优先级为:品种一致 > 毛色一致 > 城市一致 > 时间相近。 - 匹配结果按得分倒序返回给Android端,展示相似度标签("品种匹配""地区匹配")。
实际编码时,最简单的做法是先把同城市的候选集查出来,再用simHash做一次轻量模糊匹配。但毕业设计用不到那么复杂,SQL里LIKE拼多个条件,再加一个布尔字段标记匹配类型就完全够了。
这个功能做得好的话,答辩时可以清晰地讲出"走失登记"和"拾获登记"两种数据的价值——它们不是孤立的两个模块,而是通过匹配引擎产生连接的,这也是题目里"宠物寻主系统"这个词的落点。
5.4 消息通知:状态变更怎么让用户及时知道
消息通知我建议用最轻量的方案:申请审核通过/拒绝后,后端在状态变更的同一个事务里插入一条message记录,Android端在"我的消息"页面拉取未读消息列表。这样不用引入WebSocket或推送SDK(极光推送、个推等),演示效果和闭环性也足够。
实现细节:
message表字段:id、user_id、type、content、is_read、create_time。- 当管理员审核申请时,Service层调
messageService.notify(userId, "您的领养申请已通过审核...")。 - Android端进入消息页面时请求未读接口,并用
BadgeView在底部导航栏显示未读角标。
如果想让体验更好,可以在Android端加一个定时器每30秒轮询未读数量,但这个在毕业设计里可选,不是必要项。
6. 常见问题排查与避坑速查表
6.1 后端常见问题
| 症状 | 原因 | 解法 |
|---|---|---|
| 8080端口被占用 | 其他程序占用 | 改端口或kill占用进程 |
| 数据库中文乱码 | 连接串没指定字符集 | JDBC URL加characterEncoding=utf8,库表和连接串都统一utf8mb4 |
| MyBatis-Plus自动填充不生效 | 缺少@TableField(fill = FieldFill.INSERT) | 在实体字段上声明,配置MetaObjectHandler |
| LocalDateTime返回格式是数组 | Jackson配置问题 | 配置spring.jackson.date-format或实体加@JsonFormat |
| 上传的图片重启后丢失 | 本地路径存储 | 做好目录规划,或改OSS(但毕设不需要) |
这里重点提醒一下SpringBoot 版本问题:现在下载SpringBoot Init时默认是3.x,而3.x要求JDK 17,很多同学电脑装的是JDK 8,一启动就报错。做毕业设计我强烈建议用2.7.18+ JDK 8 的组合,资料多、插件兼容性好、遇到问题百度一搜全是答案。如果用3.x,注意原来javax.*的包全部变成了jakarta.*,很多老教程代码不适用。
6.2 Android端常见问题
| 症状 | 原因 | 解法 |
|---|---|---|
| 网络请求一直失败 | BASE_URL地址错误/防火墙拦截 | 用10.0.2.2或局域网IP,检查防火墙 |
| 图片加载不出来 | 明文HTTP被禁止 | 加usesCleartextTraffic="true" |
| 图片上传后预览成横的 | 未处理 Exif 旋转信息 | 用Glide或自定义工具读取Exif并转正 |
| 真机安装APK后无法连接后台 | 手机与电脑不在同一网段 | 连同一个WiFi,后端监听0.0.0.0 |
| 列表只加载一页 | 分页参数传错 | 检查pageNum、pageSize参数名是否与后端一致 |
| Token过期后页面无反应 | 未统一处理401 | 全局拦截401并跳登录 |
6.3 答辩与演示前必做的几件小事
根据我帮人调试的经验,演示翻车大多不是技术问题,而是准备不足:
- 预置数据一定要多。至少放20只不同品种、不同状态的宠物,3条走失信息、3条拾获信息。现场现发现传图容易卡顿。
- 网络环境要提前确认。演示用的WiFi下,手机和电脑IP要互ping通。很多学校教室的WiFi是AP隔离的,手机和电脑根本不在同一网络,这时候建议直接用模拟器(模拟器走
10.0.2.2不受影响),或者提前把后端部署到云服务器。 - 图片别用太大。手机拍的照片动辄5MB,上传慢还占服务器空间。Android端在上传前做一次压缩,压缩到800px宽、80%质量就够展示用。
- 准备一份接口文档。答辩时老师可能会抽查某个接口设计,直接用
springdoc-openapi或knife4j生成Swagger UI,打开浏览器现场展示接口列表和数据字段,非常加分。
6.4 一点关于"工作量"的建议
这个项目如果只是"宠物信息发布 + 领养申请",工作量明显偏少。想让系统饱满,我建议至少补上:寻主与拾获双通道、领养审核状态机、管理端审核流、消息通知。这四块加起来代码量不大,但能极大丰富业务故事线。尤其是"宠物寻主——走失报告与拾获报告互相匹配推荐"这个功能,建议一定要做,它是题目里最亮眼的点,也是很多范文根本没做透的点。
写到最后,说点实在话
带完这套项目,我最深的体会是:毕业设计重要的不是写了多少行代码,而是你有没有把一个业务闭环真正跑通。哪怕技术栈平平无奇,但只要"用户发布宠物 → 管理员审核 → 首页展示 → 他人申请 → 状态流转 → 线下领养 → 寻主匹配"每一个环节都经得起追问,答辩基本就稳了。
如果让我再提一条实打实的建议:从第一天就把"联调"当成开发的一部分,而不是最后一步。后端每写完一个接口,立刻用Postman测一遍;Android端每写完一个页面,立刻连本地后端验证一遍。拖到最后再联调,永远会爆发连环问题,而且你会分不清到底是谁的锅。
这个项目后续还能很自然地扩展成微信小程序版、管理后台Web版、甚至对接地图API做周边救助站定位。先把这一版稳稳做完,你会发现后面这些都只是量的叠加,没有任何新的坎了。祝顺利。