ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

用uni-app+SQLite打造一款极简离线刷题App

2026/9/2 22:38:55 拓冰建站 浏览量
用uni-app+SQLite打造一款极简离线刷题App 简介这是一份基于Java开发的“简单刷题app”Android工程资源主要面向初学Android开发或准备课程设计的学习者旨在通过一个轻量级在线刷题案例帮助理解移动端应用从界面搭建、页面跳转到数据存取与列表展示的常用实现方式。资源以rar压缩包提供共845个文件整体约19.57MB文件构成以xml布局与配置、png图片资源、json数据、java源码、class编译产物、jar依赖库及debug版apk为主既能看到项目源码与资源结构也能直接安装或导入Android Studio运行体验。目前已有5975人浏览学习。项目虽然仍处于开发阶段但已覆盖Activity与Intent、几种常见布局管理器、SharedPreferences与SQLite存储、Adapter及RecyclerView列表、网络请求等关键知识点并附带了构建中间产物与调试包方便对照代码与运行效果进行排查。对希望借助完整项目提升Java/Android实操能力的初学者来说这份资源提供了可读性较强的代码参考和排错思路。1. 为什么我只想做一款简单的刷题app1.1 刷题软件越做越重我的耐心越来越短手机上装过的刷题app两只手数不过来但真正坚持用下来的没几个。常见的刷题软件打开之后先是一屏弹窗签到、金币、任务、直播课、限时免费……还没开始做题注意力已经被切走了。我想要的简单刷题app不是功能越多越好而是打开就能进入做题状态题库在手里、题单已生成、点一下就下一题。这个项目就是从这样一个朴素需求出发的。简单刷题app的定位很明确个人备考场景下的离线刷题工具。支持把Excel、JSON、整理后的文本批量导入成题库提供顺序刷题、随机刷题、错题重刷、收藏练习和模拟测试所有数据都存在本地不需要联网也没有账号体系。它适合三类人一是手里已经有一堆复习资料想把它们变成手机题库的人二是在通勤、排队这类碎片时间里想快速刷题的人三是被各种激励体系打扰到崩溃只想安安静静做题的人。举个例子我有一本400多页的法规汇编考前最需要的是把里面的判断题反复刷。传统做法是拿笔在纸上划做完了还要自己翻答案用扫描软件拍下来又没法随机抽题。最后我花了两个晚上把题目整理成Excel导入简单刷题app之后每天通勤40分钟就能过掉100道判断题。这种资料在手上随时能刷的感觉是所有重运营的刷题软件给不了的。1.2 想明白刷题这个动作的本质砍需求就很容易刷题的本质是什么我用一句话概括题目呈现用户作答系统反馈重复直到掌握。反馈包括对错、答案、解析、以及后续是否再出现。凡是不服务于这个闭环的功能都可以往后放。社区讨论、点赞排行、积分商城这些东西不是没用而是会稀释核心体验。尤其是单人备考场景并不需要另一个社交平台。所以我在项目启动前先写了一份不做清单不做社区、不做积分/签到、不做排行榜、不做直播课、不做内置商城、不做AI题目生成。砍掉这些之后整个应用的核心页面只有三个题库列表、做题页、统计页。这也是我把简单直接写进名字的原因。很多人问为什么不做每日计划其实每日计划是把刷题变成任务而我想让刷题回到主动求知的状态。我可以自己决定今天刷20题还是100题而不是被app设定目标追着跑。这个取舍逻辑同样适用于技术方案。后面聊数据模型和存储方案时你会发现每个选择都是围绕离线可用、迁移方便、维护成本低这三个词展开的。2. 功能取舍MVP版本我保留了什么、砍掉了什么2.1 MVP功能清单只做能闭环的模块第一版我列了一个功能清单每个功能都问自己三个问题没有它刷题闭环会不会断没有它用户会不会放弃没有它开发成本能不能省下一大半通过之后才留了下来。模块功能说明题库管理创建题库、多题库切换、删除每个题库独立统计进度互不干扰批量导入JSON导入、Excel导入支持从复习资料一次性生成题库刷题模式顺序、随机、错题重刷、收藏练习、模拟测试顺序用于首轮学习随机用于考前巩固答题判定单选、多选、判断、填空、简答简答题采用自我判对系统只做参考答案展示错题本自动记录、连续答对后移出、手动移除错题是刷题app的核心资产收藏夹手动标记重点独立练习不参与统计但会出现在收藏练习中统计今日刷题数、正确率、累计刷题数、章节进度数据全部基于本地作答记录每个功能背后都有数据支持。比如错题本我把它设计成答错自动进、连续两次答对自动出的机制避免错题只增不减。统计页单独拉出首次正确率和历次正确率两个指标前者反映对知识点的掌握程度后者反映复习过程中的真实表现两套数据并存才不会误导自己。这个清单不是我拍脑袋定的而是参考了我平时用纸质题册时的习惯先按顺序过一遍标注错题考前只翻错题和重点题。app只是把这套流程数字化了没有改变学习方法本身。2.2 刻意不做的功能其实是在保护核心体验有一些功能做起来不难但我还是故意没有做。最典型的是账号和云同步。账号体系一旦引入就要处理注册、登录、找回密码、服务端存储、数据加密、隐私协议这套链路对单人项目来说成本太高。我的替代方案是本地存储手动导出JSON备份。用户把数据导出成文件放到网盘、电脑或者自己的NAS里换手机时再导入虽然多一步操作但完全掌控数据。还有一点值得展开不少人建议我加打卡日历和连续刷题天数我拒绝了。这类功能是利用损耗厌恶心理制造留存短期看数据好看长期看用户会被任务感压垮。刷题工具应该让人专注在题目本身而不是把今天有没有打卡变成额外的心理负担。这个判断在后来的真实使用中得到了验证——我连续用两周后每天打开app的原因就是还有一套错题没清而不是今天没打卡会断签。关于删除功能很多app把删除藏得很深担心用户误删但个人工具不需要这种设计。左滑删除、二次确认干净利落。数据是用户的用户应该随时能用最小的代价清理不再需要的题库。3. 题目数据模型与批量导入从Excel和PDF到可刷题题库3.1 题目数据结构先把字段设计稳后面才不返工刷题app的地基是题目数据结构。这块如果设计得不好后面所有功能都会别扭。我最终采用的JSON结构长这样{ id: 1001, type: single, question: 以下哪个选项描述了TCP三次握手的第二次握手, options: { A: 客户端发送SYN, B: 服务端发送SYNACK, C: 客户端发送ACK, D: 服务端发送FIN }, answer: [B], analysis: 第二次握手是服务端同时确认客户端的SYN并发送自己的SYN即SYNACK。, chapter: 网络基础, tags: [高频, TCP], difficulty: 2 }几个设计细节值得说。选项为什么用对象而不是数组因为判断题、填空题没有选项用对象可以让是否有选项直接通过options是否为空判断而数组还需要额外的选项数量字段。answer为什么统一用数组多选题答案是多个单选题答案虽然是单个但统一成数组后判定逻辑只需要写一套。判断题用[T]表示正确、[F]表示错误填空题允许填入多个可接受答案比如[三次握手, 3次握手]判定时逐个匹配。章节字段chapter和标签字段tags很重要它们决定了后续能不能按章节刷题、按标签筛选。如果没有这两个字段后面想做精细化的错题复习就得返工。3.2 JSON和Excel导入前端解析加校验比想象中简单题库来源绝大多数是Excel表格第一版支持JSON导入后很快发现用户根本不会手写JSON必须支持Excel。我用SheetJSxlsx库在前端解析Excel约定模板的列名题干、选项A、选项B、选项C、选项D、答案、解析、章节。解析出来的每一行转成题目对象同时做两层校验第一层是必填项校验题干和答案不能为空第二层是答案合法性校验单选题答案必须落在选项范围内多选题答案不能为空数组。这个校验逻辑用起来很顺手导入时如果某一行有问题不是直接报错停止而是把问题行收集起来最后统一提示第12题缺答案第15题选项C为空让用户在原表格里改完重新导入。在uni-app里H5端可以用input typefile选择文件App端我用的是plus.io相关接口选完文件后读成ArrayBuffer再交给xlsx解析。第一次跑通的时候一个3000题的题库从选择文件到导入完成只用了两秒多这个体验足够好。为了降低整理门槛我还提供了一个模板下载功能在导入页放一个按钮点击后生成一份带示例数据的Excel模板文件。用户只需要照着格式把题目粘进去就行。这个模板文件本身也是用xlsx库生成的不需要后端参与。3.3 把PDF题变成刷题题库半自动处理才是正确姿势很多复习资料是PDF格式这也是把pdf题做成刷题软件这个需求出现的原因。直接让app内嵌一个PDF解析引擎在个人项目里是不现实的。我的做法分两步第一步在电脑上把PDF转成Excel或Word。如果PDF是文字版用WPS或Acrobat直接导出如果是扫描版先OCR再复制出来。第二步把识别结果整理成上面提到的Excel模板再通过导入功能进入app。这里有个经验OCR结果往往有错字尤其是数字和字母不要指望全自动。我会在导入后设置一个待校对状态题库列表里显示未校对的题数用户刷题前可以快速过一遍。整理题库这件事本质上是一次性的体力活但做完之后换来的是未来几个月随时随地刷题的便利性价比其实很高。4. 刷题核心流程顺序、随机与错题重刷的实现4.1 作答流程与判定逻辑一套逻辑处理五种题型核心刷题界面不是最难的真正需要想清楚的是一次作答如何被记录。我的流程是点击开始刷题后根据模式生成一个题单题目ID数组然后逐题展示。用户提交答案后先调用判定函数再更新本地记录最后推进到下一题。判定函数长这样function checkAnswer(question, userAnswer) { const correct question.answer; if (question.type fill) { const userNormalized userAnswer.map(a a.trim().replace(/\s/g, )); const correctNormalized correct.map(a a.trim().replace(/\s/g, )); return userNormalized.some(a correctNormalized.includes(a)); } if (question.type multiple) { return userAnswer.length correct.length userAnswer.every(a correct.includes(a)); } return userAnswer[0] correct[0]; }多选判定很容易踩坑如果只判断用户选的都在正确答案里会漏掉漏选的情况。所以要先比较长度再比较内容。填空题答案是数组时用some表示命中任意一个就算对这符合日常使用习惯。简答题不自动判对作答后展示参考答案用户自己点答对/答错这个交互放在提交面板里避免主观题被误判。随机刷题的实现不复杂用一个Fisher-Yates洗牌算法把题单打乱就行。真正要注意的是错题重刷和随机刷题不要互相干扰错题重刷时题单从错题记录里生成随机刷题时题单从整个题库里生成两者都只是生成题单时的数据源不同后面的答题流程完全复用。4.2 错题本与收藏夹不是简单的题目ID集合错题本的第一版实现非常简单答错就把题目ID塞进一个数组后来发现完全不够用。重刷错题时我不知道这道题错了几次、上次选了什么、最近一次错误是什么时候这些信息对复习决策很重要。于是我把错题记录改成了一条独立的作答事件{ questionId: 1001, wrongCount: 3, lastAnswer: [A], lastWrongAt: 1733300382000, correctStreak: 0 }错题重刷模式会优先选correctStreak为0、且lastWrongAt更早的题目。连续答对两次后correctStreak到2自动从错题本移出。收藏夹则独立于错题本是用户主动标记的重要题目集合两个集合可以重叠一道题可以既是错题又是收藏互不影响。这种设计在代码上只增加了一个字段但对刷题节奏的影响非常大。4.3 进度与统计让数据真实反映掌握程度统计页的数据不能直接从题库的题目数里算得从作答记录里算。我用两个指标首答正确率和总体正确率。首答正确率的分子是该题第一次被作答时正确的数量分母是被作答过至少一次的题目数它衡量的是第一次见题时的掌握情况。总体正确率则是所有作答次数中正确的比例刷到第三遍时正确率会明显升高两套数据放在一起才能看出复习是否有效。进度条我用的是已首答题目数/总题目数而不是已做次数/总题目数。因为用户可能在错题模式里反复刷同几道题用作答次数算进度会虚高。这个细节让我意识到统计功能的本质不是堆数字而是帮助用户回答一个问题我到底还有多少题没真正见过哪些题需要再看一眼。5. 技术选型、离线存储与打包上架的坑5.1 为什么选uni-app而不是原生或Flutter这个项目的技术选型我纠结过一阵。原生Android写起来性能最好但我要同时兼顾iOS和H5Flutter的UI表现力强但Dart语言和状态管理方案需要额外学习成本最后选了uni-app理由有三个一是Vue3语法写起来快个人项目最怕拖二是一套代码能出Android、iOS、H5三端内部自测时H5端免安装最方便三是插件生态里已有现成的SQLite、文件选择等模块省掉大量原生代码。当然纯原生党完全可以用Kotlin写这个项目规模不大技术栈不是决定成败的因素。5.2 本地数据库与云同步MVP阶段不碰账号体系用量小的时候用uni.setStorage存JSON就够了但题库一旦上万读取和写入会变慢。我最终用SQLite存题目和作答记录配置类数据继续用本地存储。SQLite的好处是查询和联表方便比如统计某个章节的正确率一条SQL就能完成。离线可用是硬性要求刷题场景经常在地铁、电梯这些没有信号的地方数据必须本地闭环。云同步没有做前面说过账号体系成本太高。但我不能让用户数据因为卸载app而丢光所以做了导出JSON备份功能点击按钮把题库、错题本、作答记录全部打包成JSON文件保存到本地或者分享到云盘。这个方案虽然称不上优雅但在个人项目中它比自建服务器可靠得多。5.3 真机调试和打包阶段我踩过的三个坑第一个坑是键盘遮挡输入框。填空题作答时弹出的键盘会盖住答案输入框。解决方法是监听键盘弹出高度动态调整页面滚动区域同时在输入框获得焦点时滚动到可视区域内。第二个坑是安卓字体缩放导致的布局错乱。系统字体调大后用固定像素写的按钮文字会溢出最后统一改用相对单位并限制页面最大字号倍数。第三个坑是iOS签名。个人开发者在没有付费证书的情况下打不了正式安装包我的处理方式是先用H5版本做日常使用需要打包时再用TestFlight做内部测试。这三个问题都不复杂但每个都足以让新手卡一整天。5.4 后续可以怎么扩展做完MVP后我自己的使用习惯已经稳定了。如果后续还要扩展优先级我会这样排第一是支持更多导入格式比如直接从Anki的apkg文件转换第二是刷题计划提醒本地通知就行不建议做云端任务第三是多设备导入导出优化。这些功能都遵循同一个原则不破坏打开即刷的核心体验。最后分享一个我实测下来的小技巧每周把错题本导出一次备份文件名带上日期。坚持几周后你会发现这个动作不仅防止数据丢失还能顺便回顾一下这一周到底在哪些知识点上反复跌倒。刷题app做出来之后最大的成就感不是代码跑通了而是我真的靠着这套极简流程把几本厚资料的题目一遍一遍过完了。简单才是能坚持下去的理由。本文还有配套的精品资源点击获取