升级Sugar ORM到1.5并启用MultiDex后查询返回空列表/属性为空问题
我之前也碰到过一模一样的问题!结合Sugar ORM 1.5的特性和MultiDex的类加载机制,这大概率是MultiDex拆分导致Sugar无法扫描到模型类,或者初始化顺序搞反了。下面是我亲测有效的解决步骤:
1. 先搞定Application的初始化顺序
Sugar的初始化必须在MultiDex安装完成之后,不然会出现类加载异常。如果你用的是自定义Application,一定要这么写:
public class MyApp extends MultiDexApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 先装MultiDex,这步必须在所有初始化之前 MultiDex.install(this); } @Override public void onCreate() { super.onCreate(); // 再初始化Sugar SugarContext.init(this); } }
如果你的Application不能继承MultiDexApplication,就一定要在attachBaseContext里手动调用MultiDex.install,绝对不能偷懒。
2. 强制把Sugar模型类塞进主Dex
MultiDex默认会把类拆到多个dex文件里,但Sugar启动时只会在主dex里扫描模型类——如果你的EventType这类模型被分到了次dex,Sugar根本找不到它们,自然返回空列表或者空对象。
配置build.gradle(Module级别)
先确保开启MultiDex,再添加主dex规则:
android { defaultConfig { multiDexEnabled true // 如果你用AndroidX,这里改成对应的MultiDex依赖 implementation 'com.android.support:multidex:1.0.3' implementation 'com.github.satyan:sugar:1.5' } dexOptions { preDexLibraries = false // 避免预编译库导致的dex拆分问题 } }
用multiDexKeepFile指定主dex类
在项目根目录创建multidex-config.txt,把你的模型类全限定名写进去,比如:
com/yourapp/models/EventType.class com/yourapp/models/OtherModel.class
然后在build.gradle的defaultConfig里添加:
multiDexKeepFile file('multidex-config.txt')
混淆规则(如果开了混淆)
在proguard-rules.pro里加上Sugar的保护规则,防止模型类被混淆:
# 保护Sugar核心类 -keep class com.orm.** { *; } -keep class com.orm.SugarApp { *; } # 保护你的模型类包 -keep class com.yourapp.models.** { *; } -keep public class * extends com.orm.SugarRecord
3. 验证模型是否被正确扫描
可以在Application的onCreate里加个日志,确认Sugar有没有扫到你的模型:
SugarContext.init(this); List<Class<? extends SugarRecord>> scannedModels = SugarDb.getDb(this).getTableNames(); Log.d("SugarDebug", "扫描到的模型类:" + scannedModels.toString());
如果日志里看不到EventType,说明主dex配置还没生效,得再检查一遍multidex-config.txt的路径和类名。
4. 清理旧数据测试
从Sugar 1.4升级到1.5可能存在数据库 schema 变化,建议先卸载旧版本应用,清除手机上的应用数据,再重新安装测试——旧数据库结构也可能导致查询返回空结果。
最后再检查下你的EventType模型是否符合Sugar 1.5的要求:必须继承SugarRecord、要有无参构造函数、注解(如果用了)要正确,比如:
public class EventType extends SugarRecord<EventType> { private String eventName; private int eventCode; // 必须要有无参构造函数 public EventType() { super(); } public EventType(String eventName, int eventCode) { this.eventName = eventName; this.eventCode = eventCode; } // getter和setter... }
内容的提问来源于stack exchange,提问作者Hellfish90

