如何从SQLite中提取指定数据并显示到TextView?现有代码异常如何解决?
现有代码存在的问题
- 硬编码列索引极易出错:你直接用
cursor.getString(12)取第13列,依赖的是SELECT *返回的列顺序和你预期完全一致,一旦后续表结构调整(比如在前面新增字段、调整字段顺序),索引12对应的字段就会发生变化,甚至会抛出列索引超出范围的异常。同时如果你的表实际字段数不足13个,直接取索引12必然报错。 - 游标资源未释放:游标使用完成后没有调用
close()方法,会造成内存泄漏,长时间运行可能引发OOM。 - 查询操作使用写数据库实例:你只是执行查询操作,不需要调用
getWritableDatabase(),当磁盘空间满的时候getWritableDatabase()会打开失败,但读操作依然可以用getReadableDatabase()正常执行。 - 冗余的循环逻辑:你明确表只有1行数据,不需要写
do-while循环遍历所有行,直接取第一行数据即可。 - 未处理字段空值和空指针风险:如果第13列的存储值为null,
cursor.getString(12)会返回null,直接给TextView设置null值不会显示内容;同时getSupportActionBar()可能返回null,直接调用hide()会触发空指针崩溃。
优化代码方案
修改DatabaseHelper的查询方法
// 仅查询需要的目标字段,效率更高,也避免列顺序变化的影响 public String getUserName() { String userName = null; SQLiteDatabase sqLiteDatabase = this.getReadableDatabase(); // 此处将COLUMN_USER_NAME替换为你表中第13列对应的实际字段名 Cursor cursor = sqLiteDatabase.rawQuery("SELECT " + COLUMN_USER_NAME + " FROM " + TABLE_NAME, null); try { if (cursor.moveToFirst()) { // 通过列名获取索引,不受字段顺序、表结构调整影响 int columnIndex = cursor.getColumnIndexOrThrow(COLUMN_USER_NAME); userName = cursor.getString(columnIndex); } } finally { // 无论查询是否成功,都关闭游标释放资源 if (cursor != null && !cursor.isClosed()) { cursor.close(); } } return userName; }
修改Activity代码
public class showName extends AppCompatActivity { TextView name; DatabaseHelper userDb = new DatabaseHelper(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.showcvv); // 增加非空判断避免空指针 if (getSupportActionBar() != null) { getSupportActionBar().hide(); } name = findViewById(R.id.userName); String userName = userDb.getUserName(); if (userName == null || userName.trim().isEmpty()) { Toast.makeText(showName.this, "No data generate", Toast.LENGTH_SHORT).show(); // 可以设置默认显示文本,避免空白 name.setText("暂无数据"); return; } name.setText(userName); } }
额外优化建议
- 如果后续数据量变大,建议把数据库查询操作放到子线程执行,避免阻塞主线程导致界面卡顿。
- 新增表结构升级的兼容逻辑,避免版本迭代时表结构变更导致的数据读取失败。
内容的提问来源于stack exchange,提问作者user00000999
相关产品推荐
相关产品推荐

