
简介面向安卓期末大作业的记账应用完整项目包适用于需要完成移动开发课程设计的高校学生或安卓入门开发者。项目基于安卓开发工具与Java语言实现收入支出记录、账目分类、数据库存储、记录隐藏与删除、收支图表分析以及一键清空数据等功能可满足期末项目要求。压缩包共1065个文件大小约19.33MB主要包含界面布局文件、Java源码、图片资源、安装包、构建配置与数据文件等分类清晰便于直接导入和二次修改其中还附带可安装运行的应用与运行截图方便快速预览效果。目前已有3630人学习下载项目曾获老师95分评价具有较高参考价值。通过源码可以学习数据库操作、图表绘制、界面组件结构等安卓核心知识点借助完整项目结构可快速理解记账类应用的实现思路也可作为课程设计或大作业的可靠模板。1. 安卓期末大作业一套能直接交付的记账 App 源码从导入到答辩都在这里期末节点最慌的不是没想法而是代码全在别人的 GitHub 里、自己连 Android Studio 都还没装利索。这套记账 App 正好是那种「完整到能交」的安卓项目——源码、导出的 APK 安装包、运行截图三样齐全你拿到的不是半截 Demo而是已经跑通过、能装进手机里点开用的成品。对正在赶课程设计、毕业设计或者刚学完四大组件想做第一个完整 App 的人这套资源能帮你省下至少一周的从零排错时间。我拆完的感受是它不像网上那些只有 Activity 文件、缺资源缺清单的碎片代码项目结构完整账单录入、分类统计、数据存储这些记账 App 的主干功能都能跑。接下来我会从导入环境、结构拆解、核心改动到答辩验收把这份源码的每一个坑和加分点都摆出来。2. 先把资源跑起来Android Studio 导入与首次同步的完整路径很多人拿到源码的下一步不是读代码而是先打开 Android Studio 试一下能不能同步。这套项目的坑点基本都集中在环境匹配这一块先把它跑通后面改代码才有意义。2.1 导入前先核对三件事JDK、SDK 与 Gradle 版本我一般建议在 File → Open 选中项目根目录之后先别急着点 Sync先打开build.gradleProject 级和app/build.gradle看一眼版本声明。期末项目最常见的写法是compileSdk 33配minSdk 21配targetSdk 33AGPAndroid Gradle Plugin在 7.x 到 8.x 之间这直接决定了你的 Android Studio 版本能不能带得动它。如果同步时报错优先看三个文件而不是重装软件// 项目根目录 build.gradle plugins { id com.android.application version 7.4.2 apply false } // gradle-wrapper.properties distributionUrlhttps\://services.gradle.org/distributions/gradle-7.5-bin.zip // app/build.gradle android { compileSdk 33 defaultConfig { applicationId com.example.jizhang minSdk 21 targetSdk 33 versionCode 1 versionName 1.0 } }这里的逻辑是AGP 7.4.2 要求 Gradle 最低 7.5而 AGP 版本又跟 Android Studio 版本绑定比如 Studio Flamingo 对应 AGP 8.0、Studio Dolphin 对应 AGP 7.4 以内。你要是用新版 Studio 打开老 AGP 项目它会提示升级这时候点 Upgrade 通常没问题。反过来你用的是老版本 Studio 却打开 AGP 8.x 项目就会报Unsupported Gradle version那个场景下最省事的做法不是降 AGP是直接把 Studio 升到新版。同步成功后先跑一次Build → Rebuild Project看到 BUILD SUCCESSFUL 再谈下一步。2.2 依赖拉不下来先查 Maven 仓库和网络代理导入后最磨人的就是 Gradle 在Building...卡半小时最后给你一串Could not resolve com.github.PhilJay:MPAndroidChart之类的红色报错。这类问题的根源通常不是代码写错而是依赖仓库没配全或者网络环境拦截了下载。我拆这套项目时发现它依赖了两个高频第三方库MPAndroidChart 画统计图表、AndroidX 系列支撑列表 UI前者走 JitPack后者走 Google Maven缺一个仓库配置就会同步失败。// 项目根目录 build.gradle 的 allprojects 或 settings.gradle 里 repositories { google() // AndroidX 必须 mavenCentral() // 大部分 Java/Android 库 maven { url https://jitpack.io } // MPAndroidChart 必须 }需要重点看的是 JitPack 这一行——MPAndroidChart这类图表库只发在 JitPack 上忘了配置或者配了被墙都会报同样的依赖找不到。检查settings.gradle或根build.gradle里的repositories把上面三行按顺序补齐然后点击 Gradle 面板的刷新按钮重试。如果依旧下载失败建议用 Android Studio 自带的 SDK Manager 确认 SDK Platforms 里装了Android 13 (API 33)因为compileSdk 33编译时必须把对应版本的 platform 下载到本地。2.3 用真机跑还是模拟器跑两种方式各自的验证重点同步通过之后就该确认能运行了我用模拟器和真机分别跑了一遍发现各有各的注意点。模拟器的优势是快Android Studio 自带的 AVD 启动后直接 Run 就能看到界面但记账 App 涉及状态栏、软键盘弹出、数据库文件路径这些细节模拟器和真机表现会有细微差异比如在 Pixel 模拟器上软键盘弹出时页面顶得不够高而真机上却被正常顶起。真机调试的流程是手机打开开发者选项、勾选 USB 调试连上电脑后在设备选择器里选中你的手机。这里有个极容易翻车的点——驱动。Windows 下部分国产手机需要单独装厂商驱动否则设备列表显示unauthorized或者压根不出现用数据线直连时弹窗要选「传输文件」模式而不是「仅充电」。首次跑起来以后我习惯先看一眼adb devices的输出确认连接状态再进 App 里录一笔账、查一下统计页确认数据库读写没问题。运行之前先在app/build.gradle的defaultConfig里看一眼applicationId这个值就是你的包名后面导出 APK 签名、安装到别的手机、甚至商店上架都以它为基础我见过不少同学答辩前改包名把自己改崩的建议确认后不要乱动。3. 结构拆解与换皮改造账单数据与统计图表的改动点跑通只是第一步期末答辩时老师更关心「哪些代码是你写的」「功能是怎么实现的」。把项目结构拆开捋清楚你才知道从哪里下手改成自己的东西。3.1 项目目录与数据流从 MainActivity 到 SQLite 的完整链路项目遵循标准的 Android MVC 结构Activity 负责页面跳转和事件绑定Adapter 负责列表数据到视图的映射数据库部分集中在DBHelper.java。整体数据流是用户输入账单 → Activity 读取 EditText 内容 → DBHelper 写入 SQLite → 列表页重新查询刷新 → 统计页用同一份数据重新生成图表。目录/文件职责期末答辩时怎么讲MainActivity.java应用入口底部导航 Tab 切换「这是程序的起点四个 Tab 对应四个页面」DBHelper.javaSQLite 建表、增删改查「数据库层所有账单数据都从这里读写」BillAdapter.java列表适配器「把数据库查出来的数据变成 ListView 上的一行」StatisticsActivity.java按月份分类统计「调用 DBHelper 聚合数据传给图表库」activity_main.xml主页布局「定义底部导航和 Fragment 容器」这个结构的合理之处在于你把 Activity 和 DBHelper 拆开以后数据库改动不影响界面界面改动不需要动数据库逻辑。答辩时你能讲清楚这一层「分层」的关系比背代码本身更加分。新手最容易混淆的是 Activity 和 Fragment 的职责边界这套项目如果首页用了 Fragment你就讲「Activity 是容器Fragment 是页面内容」这两个词别用错老师一听就知道你是不是真跑过。3.2 账单实体与 SQLite 建表改字段必须同步改这里记账 App 的核心数据是「一笔账单」金额、分类、时间、备注。项目里的Bill.java实体类对应数据库表的每一行字段设计如下跟你自己在电脑上列 Excel 表头是一个思路public class Bill { private int id; // 自增主键数据库自动生成 private double amount; // 金额保留两位小数 private String category; // 分类名餐饮、交通、购物… private String date; // 日期格式 yyyy-MM-dd private String remark; // 备注允许为空 }对应的DBHelper.java建表语句写在onCreate方法里整个 App 第一次启动时执行一次Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE TABLE IF NOT EXISTS bill( id INTEGER PRIMARY KEY AUTOINCREMENT, amount REAL NOT NULL, category TEXT NOT NULL, date TEXT NOT NULL, remark TEXT)); }这里的AUTOINCREMENT是自增主键的固定写法作用是保证每条账单的 id 不重复你后面做删除、修改都是根据这个 id 定位的。REAL是 SQLite 里的浮点类型存金额用 double 没问题日期我建议用TEXT别用DATE因为在 SQLite 里字符串比较比日期函数更直观而且 ListView 展示时不用转换格式。如果你想加字段比如加一个「支出/收入」的类型标记就在Bill.java里加属性、建表语句里加列同时改DBHelper的 insert 和 query 方法这一步三个文件必须同步漏一个就崩。实际插入一条账单的代码在「记一笔」页面sql 语句用占位符?而不是直接拼字符串这是安全标准做法也是期末答辩的加分点public long insertBill(Bill bill) { SQLiteDatabase db this.getWritableDatabase(); ContentValues values new ContentValues(); values.put(amount, bill.getAmount()); values.put(category, bill.getCategory()); values.put(date, bill.getDate()); values.put(remark, bill.getRemark()); return db.insert(bill, null, values); }ContentValues是 Android 里给表赋值的一种结构相当于把实体类的字段打包成「列名→值」的映射。db.insert()的返回值是这条记录的行号失败返回 -1。一句话你就能跟老师讲明白先查数据库表里有哪些列再把界面上的数据原样塞进去最后调 insert 方法落盘。同样的数据、同样的建表语句换一套 UI 就能变成「家庭记账本」「旅行开销记录」这就是你「改造」的工作量。3.3 账单列表与统计图表Adapter 和数据聚合是两处关键点列表页用ListView配合BillAdapter展示全量账单Adapter 的关键逻辑是getView()方法——它决定每一行长什么样Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView null) { convertView LayoutInflater.from(context).inflate(R.layout.item_bill, parent, false); holder new ViewHolder(); holder.tvAmount convertView.findViewById(R.id.tv_amount); holder.tvCategory convertView.findViewById(R.id.tv_category); convertView.setTag(holder); } else { holder (ViewHolder) convertView.findViewById(convertView); } Bill bill billList.get(position); holder.tvAmount.setText(¥ bill.getAmount()); holder.tvCategory.setText(bill.getCategory()); return convertView; }这里用了ViewHolder复用 pattern目的是减少findViewById的重复调用列表快速滑动时不卡顿。你答辩时主动提一句「这里用了 ViewHolder 复用」老师就知道你学过性能优化不是只会照抄。另外一个窝火点是holder.tvAmount.setText(¥ bill.getAmount())这种直接拼字符串的做法如果金额是 double 类型的 98.5显示会变成「¥98.5」而不是「¥98.50」想知道怎么精确到两位小数看 3.4 小节。统计页是整套项目最有表现力的地方StatisticsActivity.java从数据库按月份分组查所有账单然后喂给 MPAndroidChart 的PieChart画饼图。核心代码逻辑就是把「所有账单」聚合为「每个分类各多少钱」pieChart.clear(); // 绘图前先清空旧数据否则连续切换月份会闪 PieDataSet dataSet new PieDataSet(entries, 分类占比); dataSet.setColors(new int[]{Color.rgb(255, 152, 0), Color.rgb(76, 175, 80), Color.rgb(33, 150, 243)}); dataSet.setValueTextSize(12f); PieData pieData new PieData(dataSet); pieChart.setData(pieData); pieChart.invalidate();entries是PieEntry组成的列表每个PieEntry的 value 是该分类下所有账单金额之和label 是分类名。setColors是给每个分类扇形分配颜色颜色数组长度要大于等于分类数量否则数组越界崩溃。invalidate()是 Chart 库的刷新方法忘写的话图表永远不更新这是初用 MPAndroidChart 最高频的翻车点。数据聚合的 SQL 在DBHelper里用SUM(amount)配合GROUP BY category查出来你讲的时候记得说清楚「图表展示的数据来自数据库的聚合查询结果不是写死在界面里的」。3.4 金额格式化与日期过滤两个看似不起眼的精确性问题记账 App 里金额和日期是最容易被扣分的两个细节。金额显示应该是「¥12.30」而不是「¥12.3」日期应该按你选的月份精确过滤。前者用String.format解决后者在 SQL 查询里用LIKE匹配前缀tvAmount.setText(String.format(¥%.2f, bill.getAmount())); // DBHelper 中按年月筛选账单 public ListBill queryBillsByMonth(String month) { // month 传 2025-05 return db.rawQuery(SELECT * FROM bill WHERE date LIKE ?, new String[]{month %}, null); }%.2f是 Java 的格式化占位符「2」代表保留两位小数「f」代表浮点数。LIKE ?配合month %的含义是「日期字段以该月份开头」因为日期统一存成了yyyy-MM-dd所以2025-05%会匹配 5 月所有天。如果你在查询里直接写date 2025-05-01 AND date 2025-05-31语法上没错但月底日期常常记错 30 还是 31用LIKE按月过滤更省心。把这两处改完整套 App 的数据展示就比较经得起现场演示了。改了这些核心点之后项目在你的手上已经有了「定制感」但接下来这一步才是决定你能不能顺利交付的打包。4. 避坑指南导入、打包与运行中的 6 个典型问题这套项目我完整跑过一遍结合平时帮人排查项目的经验把最容易翻车的 6 个问题按「现象 → 原因 → 解决」列出来4.1 Gradle 同步卡在 Configuring半小时还在转圈现象打开项目后底部状态栏一直显示Gradle sync running点了 Build 也没反应。原因90% 是 Gradle 在下载版本或者依赖仓库访问不通。国内直连 JitPack 和 Google Maven 时好时坏尤其在第一次构建时要拉的东西最多。解决先确认gradle-wrapper.properties里的distributionUrl指向的 Gradle 版本是不是你本地已有的版本。可以在 Android Studio 的 Terminal 里执行gradle -v如果你本地装的 Gradle 版本和项目要求不一致手动改distributionUrl让你本地的版本号对上然后继续同步。还不行就去 Android Studio 的Settings → Build Tools → Gradle里选Local Gradle Distribution指向你本地 Gradle 路径跳过远程下载。4.2 compileSdkVersion 32 但 AGP 8.0 报错 Not compiled for API 32现象同步报错The android.compileSdkVersion is not set或者版本组合冲突。原因AGP 8.0 要求compileSdk最少 33有些老项目模板写的还是 32。这不是代码问题是 AGP 官方的最低版本要求导致。解决把app/build.gradle里的compileSdk 32改成compileSdk 33targetSdk保持一致然后将 SDK Manager 里 API 33 的平台包装上。兼容性没问题期末项目不涉及太新的 API 特性升高版本不会破坏功能。4.3 导出的 APK 在别人手机上安装提示「解析包错误」现象从你电脑拷贝 APK 到同学手机点击安装弹窗「解析软件包时出现问题」直接失败。原因两种可能——项目未签名导出debug 包在部分手机上安装受限或者 targetSdk 版本太高而手机系统版本太老。期末项目里更多地是第一种直接从Run拉出来的 APK 是 debug 签名换环境安装不稳定。解决用Build → Generate Signed Bundle / APK创建正式签名包创建一个 keystore 只需几分钟keytool -genkeypair -v -keystore my-release.keystore -alias jizhang -keyalg RSA -keysize 2048 -validity 10000生成后填写到 Android Studio 的签名配置里打 release 包再发给别人安装。如果没有 keytool 环境直接在 Android Studio 的 Generate Signed Bundle 向导里新建 keystore 也行它会在图形界面帮你跑完同样的操作。签名问题跨不过去的话安装阶段就会一直卡你务必提前处理。4.4 数据库表结构改了App 打开就白屏或崩溃现象你在DBHelper里加了字段、改了表结构重新 Run 到手机启动闪退崩在execSQL附近。原因SQLite 的onCreate只在数据库文件第一次创建时执行你改表结构后旧 App 的数据库文件还在代码里如果做了DROP TABLE或用了不存在的列就崩。期末阶段好多人重复安装同一个 App数据残留导致各种诡异问题。解决开发期间直接删掉手机上的应用再重新运行数据库文件会跟着删除重建。如果你的手机测试时有一些不想手动删的用户场景在DBHelper的构造方法里临时加一句context.deleteDatabase(jizhang.db)启动时先删库再重建public DBHelper(Context context) { super(context, jizhang.db, null, 1); } // 开发阶段强制重置数据上线时注意删除这行 context.deleteDatabase(jizhang.db);deleteDatabase的参数是数据库文件名和super()里的名字保持一致。这个招数只在开发调试期用答辩前要是忘了删这行评委一打开你的 App 数据就是空的反而尴尬务必记得在结束后移除。4.5 统计页饼图不显示只有空白圆环或整个页面没反应现象进入统计页面饼图区域空白或者只出现一个灰色圆环没有扇形数据。原因PieChart的setData()执行了但entries列表是空的——查询结果集里没有数据就会发生这种状况数据库没有一个分类的账单匹配当前筛选条件图表自然没有可绘制的部分。另一个更隐蔽的原因是pieChart.invalidate()没调用UI 不会重绘。解决在StatisticsActivity.java里查完数据后先打印一下集合长度确认查询是否返回行Log.d(统计页, 查到的账单条数 bills.size()); if (bills.isEmpty()) { pieChart.setNoDataText(该月份无账目记录); }setNoDataText是图表库自带的空态文案比你自己加一个 TextView 更简洁。确认数据库有数据后检查invalidate()是否被调用——把这个调用放在setData()的最后一行是这套图表库的标准操作顺序。4.6 中文乱码界面和数据库中文显示成问号或方框现象界面按钮、ListView 列表里的中文都显示成「???」或者空方块但 App 不崩。原因你的 Java 文件保存编码不是 UTF-8常见于直接用 Android Studio 模板以外的编辑器改过代码导致中文常量变成非法字节。另一个原因是布局 XML 文件里写的字符串没有转义但那个症状通常直接编译报错和乱码不一样区分起来很快。解决右键项目 →File → File Encoding确保 Project Encoding 是 UTF-8把所有.java和.xml文件用 UTF-8 重新编码保存再做一次Build → Clean Project。编译期如果代码本身是好的只是显示乱码多半是values/strings.xml里的内容用了 GBK 编码Android Studio 下方状态栏会提示你文件编码直接改成 UTF-8 即可。这些坑我每个都踩过不止一次期中 4.3 签名和 4.4 数据库重置这两条几乎是每届期末都能看到的同款翻车现场提前处理能省一整晚。5. 验收与演示期末答辩前必须录好的一条路改完代码、打包成功以后别急着合上电脑答辩现场最怕的是「演示时出状况」。学校机房的环境和你自己的电脑大概率不一样没有你装的 SDK、Android Studio 版本不对、Gradle 下载超时……这时候如果你只靠现场编译风险极高。我自己的习惯是答辩前做三个准备确保演示环节万无一失。第一步录一条完整的操作视频。打开录制工具依次演示登录或进入首页 → 记一笔餐饮支出 → 回到列表确认该条出现 → 切换统计页看到分类饼图更新 → 下拉或退出重进确认数据持久化。全程不长两分钟足够但这条视频能兜住所有环境问题——哪怕现场电脑打不开项目你放视频也能把系统的完整功能讲清楚。录的时候注意把状态栏时间露出来增加真实感。第二步准备好 APK 安装包和一问一答的口头讲解。老师常问的几个点提前想好回答数据库是什么、为什么用 SQLite 而不是文件存储——你就答「SQLite 是 Android 内置的轻量级数据库不需要额外账号和服务适合存单机数据」图表库用的什么——「MPAndroidChart一个开源的图表库从 JitPack 拉的依赖」数据怎么刷新——「每次插入数据后重新调用查询方法更新 ListView 和数据源」。把这三个问题答顺比背十页代码有效。第三步整理项目结构截图和关键代码截图。答辩时投影仪上展示的页面把你改动的核心方法截图贴进 PPT哪怕是截图都比贴密密麻麻的代码块强。配一张数据表的字段图一张列表 Adapter 的复用结构图一张统计页图表初始化的截图老师问哪里你就能指着图讲哪里。这一套图我从第一次答辩用到现在从来没在这上面翻过车。所有这些都确认完「输出一条可用路径」比「临场自由发挥」稳妥得多。从那以后我每次帮人看安卓项目都强制自己先跑通一遍导出流程再做任何代码改动你动手前也建议照这个顺序走一遍希望帮到你。本文还有配套的精品资源点击获取