恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

安卓 rawQuery 查询结果绑定 ListView:Cursor 到 Adapter 的完整实现与 TaoToken 配置验证

  • 首页
  • 资讯中心
  • /
  • 安卓 rawQuery 查询结果绑定 ListView:Cursor 到 Adapter 的完整实现与 TaoToken 配置验证

相关资讯

基于YOLOv8的电动车头盔检测系统:从数据标注到部署实战 2026/10/18 10:01:48
程序员职业倦怠自救指南:7个心态调整法,把能量省下来 2026/10/18 9:56:48
旧房改造,补的是几十年积累的“老化欠账” 2026/10/18 9:56:48

最新资讯

高校教师在线学习平台设计与开发:Vue3+Node.js+Element Plus实战
MATLAB实现RD算法的SAR点目标成像全流程
Flutter插件适配OpenHarmony:flutter_web_auth OAuth2授权流程实战
三国演义人物关系词云:从文本清洗到可信可视化的完整实践
高校AI智能体大赛:如何养好你的第一只“龙虾”
拆解 openCode 源码:用 TaoToken 统一 Key 打通全平台 AI 编程助手

今日推荐

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本周热门

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

安卓 rawQuery 查询结果绑定 ListView:Cursor 到 Adapter 的完整实现与 TaoToken 配置验证

发布时间:2026/10/18 10:01:48
安卓 rawQuery 查询结果绑定 ListView:Cursor 到 Adapter 的完整实现与 TaoToken 配置验证 1. 安卓 rawQuery 查询结果绑定 ListView 的完整场景拆解db.rawQuery()是 Android 里最直接的 SQL 查询入口它返回一个Cursor你可以把它理解成一张“游标卡在结果集上的临时表”。问题在于Cursor本身不会自己显示到界面上ListView 也不认识 Cursor中间必须有一个 Adapter 做翻译。很多新手卡住的地方不是 SQL 写错而是 Cursor 拿到了、ListView 也写好了但列表就是空白或者一滑动就崩。这篇内容适合三类人刚学 Android 数据库、用 SQLite 做本地缓存、需要在列表里展示查询结果的开发者。核心检索词就是“安卓 rawQuery 查询结果绑定 ListView”我会把SimpleCursorAdapter和自定义CursorAdapter两种写法都跑一遍再把列名映射、_id主键、Cursor 生命周期关闭这些坑讲透。最后补一段用 TaoToken 统一 Key/API 通道做接口调试的配置验证方便你在本地数据库之外把网络请求也纳入同一套调试流程。先说结论rawQuery返回的 Cursor 要绑定到 ListView必须满足三个条件——Cursor 里有名为_id的列、Adapter 的列名数组和布局控件 ID 数组一一对应、Cursor 在 Activity 销毁时正确关闭。少一个轻则空白重则IllegalArgumentException: column _id does not exist。我试过最典型的翻车场景SQL 写的是SELECT name, age FROM userSimpleCursorAdapter 构造时直接传这个 Cursor结果一运行就崩。原因就是 SimpleCursorAdapter 内部依赖_id做稳定 ID查询里没带它。改成SELECT _id, name, age FROM user立刻正常。这个细节在官方文档里一笔带过但实际开发中命中率极高。下面从建库建表开始一步步把可复制的代码给全。2. TaoToken 前置配置统一 Key 与 API 通道在写 Adapter 之前先把调试通道搭好。TaoToken 的作用是把模型调用、接口调试的 Key 和 Base URL 统一到一处避免你在多个平台之间来回切换配置。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。你需要先拿到 API Key。进入控制台创建密钥地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 页面生成一个 Key形如sk-xxxx。这个 Key 后面会同时用于模型对话和 Coding Plan 场景。如果你用的是 Claude Code 这类命令行编码工具配置方式是在项目根目录或用户目录下写 settings 文件。以 Claude Code 的 Anthropic 兼容配置为例Base URL 填https://taotoken.net/apiKey 填你刚生成的Model ID 按你实际要用的模型填。三件套缺一不可Base URL、Key、Model ID。很多人只填了 Key 就报 401就是因为 Base URL 还指向默认地址。对于 Android 项目里的接口调试你可以在local.properties或BuildConfig里注入这个 Key但注意不要提交到 Git。更稳妥的做法是用环境变量或 Gradle 的gradle.properties本地覆盖。下面给一段可复制的settings.json片段路径按你的工具实际位置放{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的实际Key, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }如果你用的是 Codex 的auth.json结构类似把 Base URL 和 Key 填进对应字段即可。Cline MCP 场景下则是在 MCP 配置里指定 command 和 env把ANTHROPIC_BASE_URL指向 TaoToken 的 API 地址。这三种配置的共同点就是三件套必须齐全少一个都会在请求阶段报错。配置完成后你可以先用模型对话页面验证 Key 是否生效地址是 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 发一条简单消息能正常返回就说明通道通了。这一步做完再回到 Android 的 Cursor 绑定心里就有底了。3. 可复制配置SimpleCursorAdapter 与自定义 CursorAdapter 两种写法先建库建表。假设我们有一个user.db表结构如下CREATE TABLE user ( _id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, age INTEGER NOT NULL );插入几条测试数据SQLiteDatabase db helper.getWritableDatabase(); db.execSQL(INSERT INTO user (name, age) VALUES (张三, 28)); db.execSQL(INSERT INTO user (name, age) VALUES (李四, 32)); db.execSQL(INSERT INTO user (name, age) VALUES (王五, 25));3.1 SimpleCursorAdapter 写法布局文件item_user.xml?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightwrap_content android:orientationhorizontal android:padding12dp TextView android:idid/tv_name android:layout_width0dp android:layout_heightwrap_content android:layout_weight1 android:textSize16sp / TextView android:idid/tv_age android:layout_widthwrap_content android:layout_heightwrap_content android:textSize16sp / /LinearLayoutActivity 里的绑定代码public class MainActivity extends AppCompatActivity { private SQLiteDatabase db; private Cursor cursor; private SimpleCursorAdapter adapter; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DBHelper helper new DBHelper(this); db helper.getWritableDatabase(); cursor db.rawQuery(SELECT _id, name, age FROM user, null); ListView listView findViewById(R.id.list_view); adapter new SimpleCursorAdapter( this, R.layout.item_user, cursor, new String[]{name, age}, new int[]{R.id.tv_name, R.id.tv_age}, 0 ); listView.setAdapter(adapter); } Override protected void onDestroy() { super.onDestroy(); if (cursor ! null !cursor.isClosed()) { cursor.close(); } if (db ! null db.isOpen()) { db.close(); } } }关键点new String[]{name, age}是 Cursor 里的列名new int[]{R.id.tv_name, R.id.tv_age}是布局里的控件 ID两者顺序必须严格对应。_id列虽然不显示但必须查出来否则 SimpleCursorAdapter 会抛异常。3.2 自定义 CursorAdapter 写法当列表项需要更复杂的逻辑比如根据年龄显示不同颜色就继承 CursorAdapterpublic class UserCursorAdapter extends CursorAdapter { public UserCursorAdapter(Context context, Cursor c, int flags) { super(context, c, flags); } Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return LayoutInflater.from(context) .inflate(R.layout.item_user, parent, false); } Override public void bindView(View view, Context context, Cursor cursor) { TextView tvName view.findViewById(R.id.tv_name); TextView tvAge view.findViewById(R.id.tv_age); String name cursor.getString(cursor.getColumnIndexOrThrow(name)); int age cursor.getInt(cursor.getColumnIndexOrThrow(age)); tvName.setText(name); tvAge.setText(String.valueOf(age)); if (age 30) { tvAge.setTextColor(Color.RED); } else { tvAge.setTextColor(Color.BLACK); } } }绑定到 ListViewcursor db.rawQuery(SELECT _id, name, age FROM user, null); UserCursorAdapter adapter new UserCursorAdapter(this, cursor, 0); listView.setAdapter(adapter);getColumnIndexOrThrow比getColumnIndex更安全列名写错会立刻抛异常而不是返回 -1 导致后续取值错乱。newView只负责创建视图bindView负责填数据CursorAdapter 会自动复用视图不要在这两个方法里做耗时操作。3.3 列名映射对照表Cursor 列名布局控件 ID类型说明_id不映射INTEGER必须存在Adapter 内部使用nameR.id.tv_nameTEXT对应第一个 TextViewageR.id.tv_ageINTEGER对应第二个 TextView如果查询里用了别名比如SELECT name AS user_name那new String[]里就要写user_name不是name。这个映射关系是字符串匹配大小写敏感。4. 验证请求与成功结果从 Cursor 到列表渲染代码写完后运行验证分三步。第一步确认 Cursor 有数据。在rawQuery之后加一行日志Log.d(CursorTest, count cursor.getCount());如果输出count 0说明查询没查到数据先检查插入语句是否执行、表名是否正确。如果输出count 3说明 Cursor 正常。第二步确认 Adapter 绑定成功。在setAdapter之后加Log.d(CursorTest, adapter count adapter.getCount());adapter.getCount()应该等于 Cursor 的行数。如果不等检查new String[]里的列名是否都在 Cursor 中存在。第三步观察界面。正常情况下ListView 会显示三行分别是张三 28、李四 32、王五 25其中李四和王五的年龄文字是红色因为年龄大于 30 的只有李四王五 25 应该是黑色这里按代码逻辑 age 30 才变红所以只有李四变红。如果你在调试网络接口时用了 TaoToken可以在模型对话页面发一条请求确认返回结构。比如让模型返回一段 JSON然后你在 Android 里用同样的 Key 和 Base URL 去请求对比两边结果是否一致。这一步能帮你排除是 Key 配置问题还是代码解析问题。成功结果的特征列表能正常滚动、没有CursorWindow相关警告、退出 Activity 后 Logcat 没有Cursor finalized without prior close()的提示。最后这条特别重要它意味着你的 Cursor 泄漏了。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth5.1 报错column _id does not exist这是 SimpleCursorAdapter 最经典的报错。原因就是rawQuery的 SELECT 语句里没带_id。解决方式把 SQL 改成SELECT _id, name, age FROM user。注意_id必须是下划线开头不能写成id。5.2 报错java.lang.IllegalStateException: Couldnt read row 0, col -1 from CursorWindow这个通常是getColumnIndex返回 -1 后继续取值导致的。改用getColumnIndexOrThrow让错误在列名阶段就暴露。同时检查new String[]里的列名和 SQL 里的别名是否一致。5.3 报错401 Unauthorized或local proxy failed如果你在 Android 里请求 TaoToken 的 API 时遇到 401先检查三件套Base URL 是否为https://taotoken.net/api、Key 是否以sk-开头且没有多余空格、Model ID 是否拼写正确。local proxy failed一般是本地代理配置冲突检查settings.json或auth.json里是否有多余的 proxy 字段删掉即可。5.4 报错reading choices或 OAuth 相关错误reading choices通常出现在解析模型返回的 JSON 时说明返回结构和你预期的字段不一致。先用模型对话页面确认返回格式再对照调整解析代码。OAuth 错误则多出现在 Claude Code 或 Codex 的登录态配置里检查auth.json是否过期重新生成 Key 后覆盖。5.5 Cursor 泄漏Cursor finalized without prior close()这个不是崩溃但会在 Logcat 里刷警告。解决方式就是在onDestroy里关闭 Cursor或者用try-finally包裹查询逻辑。如果你用了startManagingCursor已废弃换成手动关闭。5.6 列表不刷新rawQuery返回的 Cursor 是一次性快照数据库变了它不会自动更新。需要重新查询并调用adapter.changeCursor(newCursor)然后关闭旧 Cursor。SimpleCursorAdapter 和 CursorAdapter 都支持changeCursor方法。6. 语义一致 CTA把调试通道固定下来Cursor 绑定 ListView 这件事核心就是三件事SQL 带_id、列名和控件 ID 对齐、Cursor 记得关。把这三件事做成模板以后每次写列表都能直接套。接口调试部分建议你把 TaoToken 的配置固定到项目模板里。API Key 管理入口在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 需要长期做编码和 Agent 任务的可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。Claude Code 的 Anthropic 配置入口是 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 里面有三件套的完整填写示例。最后留一个实用技巧在bindView里不要做cursor.getColumnIndex的重复调用把它提到newView或者 Adapter 构造时缓存起来列表滑动会明显更顺。这个优化在数据量超过 500 条时体感很强。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号