首页/新闻资讯/正文详情

在 Android 应用中使用数据库:SQLite 配置与 TaoToken 接入实践

发布时间:2026/9/26 20:06:21 来源:云帆数科 栏目:资讯中心
在 Android 应用中使用数据库:SQLite 配置与 TaoToken 接入实践
1. Android 本地数据库为什么总在真机上翻车Android 应用里的 SQLite 数据库说白了就是 App 自带的一个小仓库不需要联网、不需要额外装服务建库建表、增删改查全在手机本地完成。它适合谁适合做离线记账、宠物档案、待办清单、设备日志缓存这类“数据量不大但要求随时可读可写”的场景。我见过太多新手在模拟器上跑得好好的一换真机就报no such table或者attempt to write a readonly database根因往往不是 SQLite 本身而是建表语句、版本号、Context 三者没对齐。这篇就按“能跟做”的标准来先交付一份可复制的SQLiteOpenHelper配置片段再补一个settings.json骨架最后用具体命令验证查询是否生效并完成一次 AI 辅助的 SQL 校验。整个过程围绕 Android、数据库、SQLite 三个关键词展开不绕弯子。需要提前说明的是AI 辅助这一环我走的是统一 Key/API 通道也就是 TaoToken。它的作用是把模型调用收敛到一个入口省得你在多个平台之间来回切 Key。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 后面配置里会用到。2. 前置准备TaoToken Key 与项目骨架在写数据库代码之前先把两件事定下来一是 Android 项目本身能编译运行二是 AI 通道的 Key 拿到手。数据库部分不依赖网络但 AI 辅助生成 SQL 和排查报错需要它。2.1 获取统一 Key进入控制台创建 API Key地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。创建后复制那串以sk-开头的字符串先存到本地临时文件里别直接硬编码进 Git 仓库。如果你后面要做长期编码或 Agent 类任务可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。只是偶尔校验 SQL 的话用按量计费的 Key 就够了。2.2 settings.json 骨架很多同学问“Key 放哪”我一般建议放在项目根目录一个不进版本控制的settings.json里再由构建脚本或本地读取逻辑注入。骨架如下{ ai: { provider: taotoken, baseUrl: https://taotoken.net/api, apiKey: sk-替换成你自己的Key, model: claude-sonnet-4-20250514, timeoutMs: 30000 }, database: { name: shelter.db, version: 1 } }注意baseUrl后面不要多加/v1之类的后缀按文档给的根地址填。model字段按你实际可用的模型名替换这里只是示例。把这个文件加进.gitignore避免 Key 泄露。2.3 依赖与权限SQLite 是 Android 框架自带的不需要额外 Gradle 依赖。如果你要用网络请求调 AI记得在AndroidManifest.xml里加uses-permission android:nameandroid.permission.INTERNET /数据库读写本身不需要任何权限这点和外部存储不一样别被网上老教程带偏。3. 可复制配置Contract 类与 SQLiteOpenHelper这一章是全文的技术核心篇幅会给足。按 Android 官方推荐的两步走先定义 schema 和 contract再用SQLiteOpenHelper建库。3.1 为什么要有 Contract 类直接拼 SQL 字符串最容易出的错就是列名拼写不一致比如建表时写breed查询时写成breeds编译期不报错运行期直接崩。Contract 类把表名、列名都收成常量改一处即可全局生效。三个理由定义架构、避免拼写错误、方便升级。3.2 PetContract 完整代码在项目主包下新建data包创建PetContract.javapackage com.example.pets.data; import android.provider.BaseColumns; public final class PetContract { private PetContract() {} public static final class PetEntry implements BaseColumns { public static final String TABLE_NAME pets; public static final String _ID BaseColumns._ID; public static final String COLUMN_PET_NAME name; public static final String COLUMN_PET_BREED breed; public static final String COLUMN_PET_GENDER gender; public static final String COLUMN_PET_WEIGHT weight; public static final int GENDER_UNKNOWN 0; public static final int GENDER_MALE 1; public static final int GENDER_FEMALE 2; } }这里implements BaseColumns会自动带上_id列省得自己声明主键常量。性别用整数枚举0/1/2 分别对应未知、公、母比存字符串省空间也更好校验。3.3 PetDbHelper 完整代码同包下创建PetDbHelper.java继承SQLiteOpenHelperpackage com.example.pets.data; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.example.pets.data.PetContract.PetEntry; public class PetDbHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME shelter.db; private static final int DATABASE_VERSION 1; private static final String SQL_CREATE_PETS_TABLE CREATE TABLE PetEntry.TABLE_NAME ( PetEntry._ID INTEGER PRIMARY KEY AUTOINCREMENT, PetEntry.COLUMN_PET_NAME TEXT NOT NULL, PetEntry.COLUMN_PET_BREED TEXT, PetEntry.COLUMN_PET_GENDER INTEGER NOT NULL, PetEntry.COLUMN_PET_WEIGHT INTEGER NOT NULL DEFAULT 0);; private static final String SQL_DELETE_PETS_TABLE DROP TABLE IF EXISTS PetEntry.TABLE_NAME; public PetDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } Override public void onCreate(SQLiteDatabase db) { db.execSQL(SQL_CREATE_PETS_TABLE); } Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(SQL_DELETE_PETS_TABLE); onCreate(db); } }几个关键点DATABASE_VERSION一旦改动 schema 就必须加一否则onUpgrade不触发onUpgrade里我用了最粗暴的删表重建生产环境要改成ALTER TABLE保留数据AUTOINCREMENT保证_id单调递增。3.4 增删改查骨架在 Activity 里拿到可写数据库对象插入一条数据PetDbHelper mDbHelper new PetDbHelper(this); SQLiteDatabase db mDbHelper.getWritableDatabase(); ContentValues values new ContentValues(); values.put(PetEntry.COLUMN_PET_NAME, Garfield); values.put(PetEntry.COLUMN_PET_BREED, Tabby); values.put(PetEntry.COLUMN_PET_GENDER, PetEntry.GENDER_MALE); values.put(PetEntry.COLUMN_PET_WEIGHT, 7); long newRowId db.insert(PetEntry.TABLE_NAME, null, values);insert返回新行 ID出错返回 -1这个返回值一定要接住判断。查询用query而不是rawQuery让框架帮你拼 WHEREString[] projection { PetEntry._ID, PetEntry.COLUMN_PET_NAME, PetEntry.COLUMN_PET_BREED, PetEntry.COLUMN_PET_WEIGHT }; String selection PetEntry.COLUMN_PET_NAME ?; String[] selectionArgs { Garfield }; String sortOrder PetEntry.COLUMN_PET_WEIGHT DESC; Cursor cursor db.query( PetEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder );?占位符配合selectionArgs是防 SQL 注入的标准做法别图省事直接拼字符串。用完cursor.close()否则内存泄漏。4. 验证请求跑通读写并做一次 AI 校验代码写完不代表数据库真的建起来了。这一章给可执行的验证步骤。4.1 用 displayDatabaseInfo 验证在 Activity 里加一个临时方法把行数打到 TextView 上private void displayDatabaseInfo() { PetDbHelper mDbHelper new PetDbHelper(this); SQLiteDatabase db mDbHelper.getReadableDatabase(); Cursor cursor db.rawQuery(SELECT * FROM PetEntry.TABLE_NAME, null); try { TextView displayView findViewById(R.id.text_view_pet); displayView.setText(pets 表行数: cursor.getCount()); } finally { cursor.close(); } }在onCreate里调用它。第一次运行会触发onCreate建表行数为 0插入一条后再运行行数变 1。如果直接崩在no such table说明建表语句没执行回去检查DATABASE_VERSION和onCreate是否被正确重写。4.2 用 adb 命令直接看库文件模拟器或已 root 的真机上可以用 adb 把数据库拉出来看adb shell run-as com.example.pets ls -l /data/data/com.example.pets/databases/ adb exec-out run-as com.example.pets cat /data/data/com.example.pets/databases/shelter.db shelter.db sqlite3 shelter.db .tables sqlite3 shelter.db SELECT * FROM pets;run-as只对 debug 包有效release 包需要 root。.tables能列出所有表如果输出为空说明建库失败。SELECT * FROM pets;能打出你插入的那条 Garfield 记录就证明读写链路通了。4.3 AI 辅助校验 SQL把建表语句丢给模型让它检查有没有语法或约束问题。走统一通道的话用 curl 就能测curl https://taotoken.net/api/v1/messages \ -H Content-Type: application/json \ -H x-api-key: sk-替换成你自己的Key \ -H anthropic-version: 2023-06-01 \ -d { model: claude-sonnet-4-20250514, max_tokens: 512, messages: [ {role: user, content: 检查这条 SQLite 建表语句是否有语法或约束问题CREATE TABLE pets (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, breed TEXT, gender INTEGER NOT NULL, weight INTEGER NOT NULL DEFAULT 0);} ] }返回里如果指出AUTOINCREMENT在 SQLite 中需要配合INTEGER PRIMARY KEY使用、NOT NULL列插入时必须给值就说明校验生效了。想直接在网页里对话验证用模型对话入口https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。5. 本篇常见错排查5.1 no such table: pets最常见。原因通常是DATABASE_VERSION没变但 schema 改了或者onCreate里execSQL的字符串拼错了。排查方法卸载 App 重装强制走一次onCreate或者把版本号加一触发onUpgrade。5.2 attempt to write a readonly databasegetReadableDatabase()在磁盘满或权限异常时会退化成只读。写操作必须用getWritableDatabase()。另外检查有没有在onCreate之外的地方误删了数据库文件。5.3 Cursor 没关闭导致内存泄漏Cursor持有底层资源不close()会累积。用try/finally包住或者用 try-with-resourcesAPI 16 的Cursor实现了Closeable。5.4 AI 请求返回 401Key 没带对或者x-api-key头写成了Authorization。不同模型接口的鉴权头不一样按文档来。Key 泄露了就去控制台吊销重建https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。5.5 真机上 adb 拉不到库run-as只对 debuggable 的包生效。检查build.gradle里debuggable true或者用 Android Studio 的 Device File Explorer 手动导出。6. 接入文档与后续路径数据库骨架跑通后AI 辅助可以继续用在两个地方一是让模型根据自然语言生成复杂查询二是把报错日志贴进去让它定位。接入细节看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你用 Claude Code 做 Android 项目Anthropic 兼容配置参考https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 。我自己的习惯是建表语句先在模型对话里过一遍确认约束没问题再写进SQL_CREATE_PETS_TABLE运行期报错就把adb logcat里那段贴进去让它给出修改建议。这样比盲改快得多。数据库版本号记得每次改 schema 都加一这个坑我踩过不止一次。

相关推荐

Ghidra逆向工程实战:从安装配置到脚本化自动化分析
Ghidra逆向工程实战:从安装配置到脚本化自动化分析

1. 为什么我最终把主力逆向工具换成了Ghidra第一次接触Ghidra是几年前的一个固件分析项目。当时手里有一套设备固件需要做漏洞挖掘,IDA Pro的授权费用让团队犹豫了很久,而免费方案里能打的实在不多。抱着试试看的心态装了Ghidra,结果一个下午… · 2026/9/26 20:05:49

AI安全测试沙箱实战:容器化隔离与渗透测试指南
AI安全测试沙箱实战:容器化隔离与渗透测试指南

1. 为什么AI安全测试不能直接上生产环境 1.1 一个真实的教训:删库只需要一条指令 去年帮一个朋友的公司做应急响应,事情的起因特别简单:他们内部搞了个AI智能体,想测试一下自动化工单处理能力,结果开发同学图省事&… · 2026/9/26 20:05:42

罗技GHUB离线安装包部署指南:21.03.24稳定版安装与避坑
罗技GHUB离线安装包部署指南:21.03.24稳定版安装与避坑

1. 为什么罗技GHUB的离线部署值得单独写一篇罗技GHUB这个驱动软件,用过罗技外设的人基本都绕不开它。G系列鼠标、键盘、耳机、方向盘,想要改键、调DPI、设宏、同步灯光,都得靠它。但问题在于,GHUB的在线安装体验一直不算稳定——下… · 2026/9/26 20:05:42

MySQL 数据库设计实战:四张核心表的 DDL 建表语句拆解与索引外键规划
MySQL 数据库设计实战:四张核心表的 DDL 建表语句拆解与索引外键规划

接手一个学校信息管理系统的数据库设计任务时,我最先动手的往往不是业务代码,而是那一张张建表语句。今天要拆的这份 schoolDB 对应的四个表的 DDL,就是我从实际项目里沉淀出来的最小闭环方案:学生表、教师表、课程表、选课成绩表… · 2026/9/26 20:50:47

禁止 Conda 自动激活 base 环境:原理与三种实用方法
禁止 Conda 自动激活 base 环境:原理与三种实用方法

作为天天跟终端打交道的人,每次打开终端,行首都挂着一个刺眼的(base),一开始还觉得挺酷,好像在提醒我“你是个玩 Python 的”,但时间一长,这玩意儿就烦了。尤其是当你在多个环境里切来切去,或者… · 2026/9/26 20:50:47

MySQL库表操作实战:从建库建表到字符集、存储引擎与锁表避坑
MySQL库表操作实战:从建库建表到字符集、存储引擎与锁表避坑

MySQL入门绕不开的就是数据库和表的操作。我见过太多新手在业务代码里写得很溜,结果一让建库建表、调字段类型、改字符集就卡壳,反而把线上环境搞出乱码、锁表、连接超时这些破事。其实数据库和表的操作才是MySQL最核心的基本功,你今天所有的… · 2026/9/26 20:50:47

Word下划线全解析:从Ctrl+U到制表位与段落下边框的排版实践
Word下划线全解析:从Ctrl+U到制表位与段落下边框的排版实践

1. 下划线这件事,远比CtrlU复杂Word里的下划线,表面上看是工具栏上一个按钮的事,但真正在文档排版里摸爬滚打过的人都知道,这里面的门道能拆出至少四个完全不同的场景:给文字加下划线、在空白处画横线、批量给特定内容… · 2026/9/26 20:50:47

SAP HCM数据表核心解析:从PA0001到簇表PCL1的查询与排错指南
SAP HCM数据表核心解析:从PA0001到簇表PCL1的查询与排错指南

干SAP项目这么多年,尤其是负责HCM模块的时候,经常会有同事把表清单打印出来贴墙上看。刚入门的顾问也喜欢问:能不能给我一份HCM数据表大全,最好是那种字母序排好的,查到哪张表直接套用。说实话,SAP HCM的数… · 2026/9/26 20:50:47

Obsidian AI集成三层架构:工具层、代理层与内核层深度解析
Obsidian AI集成三层架构:工具层、代理层与内核层深度解析

1. 这不是又一个“Obsidian速成课”:为什么24分钟必须拆解AI集成的三层逻辑你搜“Obsidian教程”,页面刷出来上百个“5分钟上手”“10分钟搭建知识库”——结果点开全是基础界面介绍、几个插件安装截图、再配上几句“强大”“自由”“双链无敌”的空泛赞… · 2026/9/26 20:50:39

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码