Firebase结合RecyclerView使用时出现无参构造函数缺失错误
解决Firebase与RecyclerView结合时的
DatabaseException无参构造函数问题 从你给出的错误日志可以直接定位到问题核心:MyItem$Sellm这个内部类没有定义无参构造函数,而Firebase Realtime Database在将数据库快照转换为Java对象时,必须依赖无参构造函数来通过反射创建实例。
问题原因
Firebase的序列化/反序列化机制工作流程是这样的:
- 先调用类的无参构造函数创建对象实例
- 再通过Setter方法或者直接访问字段(如果字段是public的)来填充数据
如果你的类只定义了带参构造函数,没有显式添加无参构造,Firebase就无法完成对象实例化,从而抛出DatabaseException。
解决方案
你需要给Sellm内部类添加无参构造函数,同时为了避免后续出现同样的问题,也要给Buy内部类和MyItem主类都补上无参构造,并且确保所有字段都有对应的Getter/Setter方法(或者将字段设为public)。
修正后的MyItem类示例
public class MyItem { // 主类字段 private Buy buy; private Sellm sell; private String title; // 主类无参构造(必须添加) public MyItem() {} // 主类带参构造(可选,根据你的业务需求) public MyItem(Buy buy, Sellm sell, String title) { this.buy = buy; this.sell = sell; this.title = title; } // 主类Getter/Setter public Buy getBuy() { return buy; } public void setBuy(Buy buy) { this.buy = buy; } public Sellm getSell() { return sell; } public void setSell(Sellm sell) { this.sell = sell; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } // ------------------------------ // Buy内部类 public static class Buy { private long buyBellow; private String date; private long stoploss; private long target1; private long target2; // Buy类无参构造 public Buy() {} // Buy类带参构造 public Buy(long buyBellow, String date, long stoploss, long target1, long target2) { this.buyBellow = buyBellow; this.date = date; this.stoploss = stoploss; this.target1 = target1; this.target2 = target2; } // Buy类Getter/Setter public long getBuyBellow() { return buyBellow; } public void setBuyBellow(long buyBellow) { this.buyBellow = buyBellow; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public long getStoploss() { return stoploss; } public void setStoploss(long stoploss) { this.stoploss = stoploss; } public long getTarget1() { return target1; } public void setTarget1(long target1) { this.target1 = target1; } public long getTarget2() { return target2; } public void setTarget2(long target2) { this.target2 = target2; } } // ------------------------------ // Sellm内部类 public static class Sellm { private String date; private long sellAbove; private long stoploss; private long target1; private long target2; // Sellm类无参构造(关键!之前缺失的就是这个) public Sellm() {} // Sellm类带参构造 public Sellm(String date, long sellAbove, long stoploss, long target1, long target2) { this.date = date; this.sellAbove = sellAbove; this.stoploss = stoploss; this.target1 = target1; this.target2 = target2; } // Sellm类Getter/Setter public String getDate() { return date; } public void setDate(String date) { this.date = date; } public long getSellAbove() { return sellAbove; } public void setSellAbove(long sellAbove) { this.sellAbove = sellAbove; } public long getStoploss() { return stoploss; } public void setStoploss(long stoploss) { this.stoploss = stoploss; } public long getTarget1() { return target1; } public void setTarget1(long target1) { this.target1 = target1; } public long getTarget2() { return target2; } public void setTarget2(long target2) { this.target2 = target2; } } }
额外注意:ProGuard配置
如果你开启了ProGuard代码混淆,一定要在proguard-rules.pro中添加规则,防止Firebase需要的类、构造函数和字段被混淆移除:
# 保留MyItem及其内部类的所有成员 -keepclassmembers class com.google.example.adinaranayaragh.MyItem { *; } -keepclassmembers class com.google.example.adinaranayaragh.MyItem$Buy { *; } -keepclassmembers class com.google.example.adinaranayaragh.MyItem$Sellm { *; }
总结
补上缺失的无参构造函数后,Firebase就能正常将数据库中的items数据转换为MyItem对象,你的RecyclerView也就能正确加载并展示这些数据了。
内容的提问来源于stack exchange,提问作者mihalca bogdan
相关产品推荐
相关产品推荐

