新闻详情

新闻详情

首页 / 资讯中心 / 详情

在 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 都加一这个坑我踩过不止一次。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

DeskcommCRM解析:融合通信与客户管理的平台设计与实践 2026/9/26 20:54:19

DeskcommCRM解析:融合通信与客户管理的平台设计与实践

1. DeskcommCRM到底解决什么问题我第一次听到"DeskcommCRM"这个名字时,第一反应是猜测它和普通CRM有什么区别。毕竟市面上叫CRM的产品一抓一大把,从Salesforce到各种国内SaaS,功能看起来都是客户管理、销售漏斗、跟进记录那一套。但…

阅读更多 →
区间二型模糊集实战:从降型算法到Python实现与避坑指南 2026/9/26 20:54:13

区间二型模糊集实战:从降型算法到Python实现与避坑指南

简介:这份文档面向模糊数学、智能控制与机器学习方向的研究者及研究生,系统梳理区间二型模糊集与模糊系统的理论脉络与应用现状。内容从Zadeh 1965年提出一型模糊集讲起,剖析其无法建模个体间不确定性的局限,进而引出1975年二型模…

阅读更多 →
黑苹果UHD 630核显7MB显存修复与硬解点亮指南 2026/9/26 20:54:13

黑苹果UHD 630核显7MB显存修复与硬解点亮指南

如果你的黑苹果装完之后,打开“关于本机”,显卡那一栏赫然写着 Intel UHD Graphics 630 7 MB,鼠标挪动像在泥里走,拖动窗口能看到明显的残影,那么恭喜,你撞上了黑苹果最经典、也最容易被新手误判的核显驱动…

阅读更多 →
从失控到可控:构建Claude Code模板体系的完整指南 2026/9/26 20:54:06

从失控到可控:构建Claude Code模板体系的完整指南

我有段时间对 Claude Code 又爱又恨,后来想明白一件事:我从来没给它准备过一套像样的 claude-code-templates。爱的是它写起代码来确实快,恨的是它老自作主张——让它修一个小 bug,它顺手把你的测试文件全部重构了;让它…

阅读更多 →
RTX 3060 12G跑通MiniMax H3视频大模型实操指南 2026/9/26 20:54:06

RTX 3060 12G跑通MiniMax H3视频大模型实操指南

1. 项目概述:一张消费级显卡跑通国产视频大模型的实操现场RTX 3060 12G跑MiniMax H3——这个标题在最近两周的AI绘画和视频生成圈子里反复刷屏。不是因为它是性能怪兽,恰恰相反,它是一次“降维打击”式的可行性验证:用一张二手市场…

阅读更多 →
SocratiCode快速上手教程:3步让AI获得深度代码搜索能力(兼容Claude Code/VS Code/Cursor) 2026/9/26 20:54:06

SocratiCode快速上手教程:3步让AI获得深度代码搜索能力(兼容Claude Code/VS Code/Cursor)

SocratiCode快速上手教程:3步让AI获得深度代码搜索能力(兼容Claude Code/VS Code/Cursor) 【免费下载链接】SocratiCode Enterprise-grade (40m LOC) codebase intelligence, zero-setup, local & private Plugin/Skill/Extension or MCP…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉