Android Studio中SQLite数据库无法插入数据/查询Bear及启动崩溃问题
嘿,看来你在Android SQLite预填充数据和查询这块踩坑了,我来帮你一步步排查解决~
首先咱们得确认数据库和预存数据到底有没有生成,这是后续排查的基础:
检查
SQLiteOpenHelper的onCreate方法
你的myDbHelper应该是继承自SQLiteOpenHelper的对吧?一定要确保onCreate里不仅正确创建了表,还执行了预填充数据的逻辑。比如:@Override public void onCreate(SQLiteDatabase db) { // 先创建表,注意SQL语法别写错! db.execSQL("CREATE TABLE bears (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);"); // 预填充数据示例 ContentValues values = new ContentValues(); values.put("name", "Grizzly"); values.put("age", 5); db.insert("bears", null, values); // 可以添加更多预存条目 }注意:如果你的应用之前已经安装过,
onCreate只会执行一次!所以如果之前的数据库没有预填充数据,直接卸载应用重装就能触发onCreate重新创建带预存数据的数据库了。可视化验证数据库
用Android Studio的「Device File Explorer」找到你的数据库文件:路径是data/data/你的应用包名/databases/你的数据库名.db,把它导出到电脑,用SQLite可视化工具(比如SQLiteStudio)打开,直接查看表结构和数据是否存在——这是最直观的验证方式。
应用崩溃的关键线索在Logcat的错误日志里!先去看日志里的异常信息,比如是SQL语法错误?空指针?找不到表?常见的坑有这些:
SQL语句拼写错误
比如表名写成bear但实际创建的是bears,列名拼写错误,或者查询时没正确用占位符(容易引发SQL注入+语法错误)。正确的查询写法应该是:public Cursor searchBear(String keyword) { SQLiteDatabase db = myhelper.getReadableDatabase(); // 用?占位符,避免语法错误和注入风险 return db.rawQuery("SELECT * FROM bears WHERE name LIKE ?", new String[]{"%" + keyword + "%"}); }Cursor处理不当
查询得到Cursor后,一定要先判断是否为空,再移动到第一行再读取数据,不然直接访问会崩溃:if (cursor != null && cursor.moveToFirst()) { do { // 读取数据,比如cursor.getString(cursor.getColumnIndex("name")) } while (cursor.moveToNext()); cursor.close(); // 记得关闭Cursor,避免内存泄漏 }数据库实例获取失败
检查myDbHelper的初始化是否正确,比如Context是否传对了,有没有在非UI线程操作数据库?(虽然查询不会直接崩溃,但耗时操作建议放子线程)
对比一下你的代码,看看哪里不一样:
public class MyDBHandler { private MyDbHelper myHelper; public MyDBHandler(Context context) { myHelper = new MyDbHelper(context); } // 搜索方法示例,返回匹配的熊名字列表 public List<String> searchBearNames(String keyword) { List<String> results = new ArrayList<>(); SQLiteDatabase db = myHelper.getReadableDatabase(); Cursor cursor = db.rawQuery( "SELECT name FROM bears WHERE name LIKE ?", new String[]{"%" + keyword + "%"} ); if (cursor != null && cursor.moveToFirst()) { do { results.add(cursor.getString(cursor.getColumnIndexOrThrow("name"))); } while (cursor.moveToNext()); cursor.close(); } db.close(); return results; } // 内部DbHelper类,负责数据库创建和预填充 private static class MyDbHelper extends SQLiteOpenHelper { private static final String DB_NAME = "BearDatabase.db"; private static final int DB_VERSION = 1; private static final String TABLE_BEARS = "bears"; public MyDbHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建表 String createTableSql = "CREATE TABLE " + TABLE_BEARS + " (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + "name TEXT NOT NULL, " + "age INTEGER)"; db.execSQL(createTableSql); // 预填充数据 prePopulateBears(db); } private void prePopulateBears(SQLiteDatabase db) { ContentValues values = new ContentValues(); // 添加第一条预存数据 values.put("name", "Grizzly"); values.put("age", 5); db.insert(TABLE_BEARS, null, values); // 添加第二条 values.put("name", "Panda"); values.put("age", 3); db.insert(TABLE_BEARS, null, values); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 版本更新时删除旧表,重新创建(测试阶段用,正式版要考虑数据迁移) db.execSQL("DROP TABLE IF EXISTS " + TABLE_BEARS); onCreate(db); } } }
最后再强调一遍:先看Logcat的错误日志!它会直接告诉你崩溃的原因,比如SQLiteException: no such table就是表没创建成功,NullPointerException就是某个对象没初始化,顺着线索修就行~
内容的提问来源于stack exchange,提问作者Rahevin

