18、数据库调试与工具:Stetho调试数据库、Facebook Realtime Database Viewer、Android Studio Database Inspector、SQLite命令行工具、日志打印技巧
数据库开发,写代码只是第一步。真正头疼的,往往是调试阶段。
数据写进去了吗?查出来对不对?那个诡异的空指针到底是因为表没建好,还是查询写错了?
我早期做Android开发时,调试数据库全靠Logcat打印Cursor内容。那叫一个痛苦。后来各种工具陆续出现,才算是把数据库调试从「黑盒」变成了「透明」。
今天,我把这些年用过的、觉得靠谱的数据库调试工具和方法,一次性梳理给你。
核心观点:数据库调试的核心,是「可视化」和「可交互」。能看表结构、能查数据、能执行SQL,你就掌握了主动权。
18.1 Stetho:Facebook开源的调试利器
Stetho是Facebook在2015年开源的工具。说实话,它刚出来时我挺兴奋的——终于可以在Chrome开发者工具里直接看数据库了。
集成方式:
// build.gradle (app)
dependencies {
implementation 'com.facebook.stetho:stetho:1.6.0'
}
// Application.onCreate()
Stetho.initializeWithDefaults(this);
启动App后,在Chrome地址栏输入 chrome://inspect,点击你的设备,就能看到「Resources」标签页。里面可以浏览表结构、执行SQL查询。
我的经验:Stetho在调试阶段非常好用,但记得上线前要移除依赖。我曾经有个版本忘记去掉,结果线上包多了几百KB的调试代码,被领导点名了。
注意:Stetho只支持debug构建。如果你在release包中保留了它,用户可能会通过Chrome查看你的数据库内容——这是严重的安全隐患。
18.2 Facebook Realtime Database Viewer
这个工具是Stetho的「轻量替代版」。它不需要Chrome,直接在App内以列表形式展示数据库内容。
集成方式:
// build.gradle
debugImplementation 'com.facebook.realtimedatabaseviewer:realtimedatabaseviewer:1.0.0'
// 在需要查看的地方
RealtimeDatabaseViewer.show(context);
我个人觉得,这个工具适合快速验证。比如你写了一个插入操作,想立刻看看数据有没有进去,直接调一下show方法就行,不用切到Chrome。
但它的缺点也很明显:功能比较单一,只能看,不能执行SQL。所以我现在用得不多。
18.3 Android Studio Database Inspector
这是Google官方在Android Studio 4.1中推出的工具。说实话,它一出来我就把Stetho扔了——因为太好用了。
使用方法:
- 运行App到模拟器或真机(API 26+)
- 点击菜单栏 View → Tool Windows → Database Inspector
- 选择你的进程,就能看到所有数据库
你可以直接浏览表数据、执行SQL查询、甚至修改数据。而且它支持Room、SQLiteOpenHelper等各种方式创建的数据库。
核心优势:不需要任何额外依赖,Android Studio自带。而且它能看到数据库的实时变化——你插入一条数据,Inspector里立刻刷新。
我记得有一次排查一个并发写入的问题,就是用Database Inspector盯着数据变化,才发现了事务没提交的bug。
限制:Database Inspector只支持API 26+的设备。如果你的App需要兼容更低版本,那就只能用Stetho或命令行工具了。
18.4 SQLite命令行工具
这是最原始、也是最强大的方式。说白了,就是直接操作数据库文件。
操作步骤:
# 1. 从设备中拉取数据库文件
adb pull /data/data/你的包名/databases/你的数据库名.db /tmp/
# 2. 使用sqlite3打开
sqlite3 /tmp/你的数据库名.db
# 3. 执行SQL
sqlite> .tables
sqlite> SELECT * FROM users;
sqlite> .schema users
为什么说它是「终极武器」?因为当其他工具都失效时(比如数据库文件损坏、或者App崩溃无法启动),你还能用命令行直接操作数据库文件。
我曾经遇到过一个线上bug,用户反馈数据丢失。我用adb pull把数据库文件拉下来,用sqlite3打开一看,发现是某个字段被意外置空了。如果没有命令行工具,这种问题几乎没法排查。
小技巧:在sqlite3中,.headers on可以显示列名,.mode column可以让输出对齐。这两个命令配合使用,查询结果一目了然。
18.5 日志打印技巧
工具虽好,但有些场景下,日志打印才是最灵活的调试方式。比如在CI/CD环境中,你没法用Database Inspector,但日志可以输出到控制台。
推荐做法:
public class DatabaseLogger {
private static final String TAG = "SQLite";
public static void logQuery(String sql, String[] args) {
Log.d(TAG, "SQL: " + sql);
if (args != null && args.length > 0) {
Log.d(TAG, "Args: " + Arrays.toString(args));
}
}
public static void logResult(Cursor cursor) {
if (cursor == null) {
Log.w(TAG, "Cursor is null");
return;
}
Log.d(TAG, "Row count: " + cursor.getCount());
while (cursor.moveToNext()) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cursor.getColumnCount(); i++) {
sb.append(cursor.getColumnName(i))
.append("=")
.append(cursor.getString(i))
.append(", ");
}
Log.d(TAG, sb.toString());
}
}
}
我个人习惯在开发阶段,给每个数据库操作都加上日志。这样一旦出现问题,直接看Logcat就能定位。
最佳实践:使用BuildConfig.DEBUG来控制日志开关。这样发布release包时,日志会自动关闭,不会泄露数据。
if (BuildConfig.DEBUG) {
DatabaseLogger.logQuery(sql, args);
}
18.6 避坑指南
说了这么多工具,最后分享几个我踩过的坑。
- Stetho和OkHttp冲突:如果你同时用了Stetho和OkHttp的网络拦截,记得在release包中移除Stetho的Interceptor,否则会报ClassNotFoundException。
- Database Inspector看不到数据:检查你的App是否在运行,以及数据库是否已经创建。有时候数据库是延迟创建的,需要先执行一次插入操作。
- sqlite3命令找不到:在macOS上,需要先安装sqlite3。用
brew install sqlite即可。Windows用户可以去官网下载。 - 日志太多影响性能:如果你在循环中打印大量日志,会导致UI卡顿。建议只在关键操作处打印,或者使用异步日志库。
嗯,数据库调试工具就这些了。每种工具都有自己的适用场景,没有绝对的「最好」。我个人建议:日常开发用Database Inspector,线上问题排查用命令行,快速验证用日志打印。灵活搭配,才能事半功倍。