Android正式版触发android.database.sqlite.SQLiteException,模拟器运行正常
搞定正式版里的SQLiteException问题
嘿,这个坑我之前踩过!你说模拟器测试一切正常,一发布正式版就炸android.database.sqlite.SQLiteException,错误还出在建表的db.execSQL行,最后补充说根源是声明环节出错——大概率是代码混淆(ProGuard/R8)把你的数据库常量给篡改了!
为啥会这样?
调试版本里ProGuard默认是关闭的,你定义的TABLE_NAME_USER_DATA、_ID_USER_DATA这些常量都保持原来的名字;但正式打包时,ProGuard会把没被保护的变量、常量重命名成短字符串(比如a、b),这就导致你建表用的是混淆后的名称,后续query的时候却还是用原常量名(或者反过来),数据库找不到对应的表/列,自然就抛出异常了。
怎么解决?
把数据库相关的常量或者整个数据库帮助类加入ProGuard的白名单,不让它被混淆:
- 如果你的常量是集中在某个类里的,打开
proguard-rules.pro,添加:-keepclassmembers class com.yourpackage.YourDbHelper { public static final java.lang.String TABLE_NAME_USER_DATA; public static final java.lang.String _ID_USER_DATA; public static final java.lang.String COLUMN_USER_NAME; // 把所有和数据库表、列相关的常量都列进去 } - 嫌麻烦的话,直接保留整个数据库帮助类不被混淆:
-keep class com.yourpackage.YourDbHelper { *; }
怎么验证?
你可以把正式打包的APK反编译,看看建表语句里的表名、列名是不是变成了莫名其妙的短名字,如果是,那就确定是混淆的锅,按上面的方法加白名单就好啦。
内容的提问来源于stack exchange,提问作者K.hamdan
相关产品推荐
相关产品推荐

