Firebase读取android.location.Location报无无参构造函数异常如何解决
错误原因
Firebase Realtime Database 反序列化数据为Java对象时,要求目标类必须包含公共无参构造方法,用于实例化对象后再通过反射给字段赋值。而系统原生的android.location.Location类未提供无参构造方法,因此调用dataSnapshot.getValue(Location.class)时直接抛出异常。
解决方案
方案1:自定义位置数据传输类(DTO)适配Firebase序列化规则
专门定义用于Firebase数据交互的位置类,符合序列化要求,同时提供转为系统Location对象的方法:// 自定义位置DTO类,适配Firebase序列化规则 public class FirebaseLocation { private double latitude; private double longitude; private long time; // 可按需添加精度、速度等其他Location相关字段 // 必须提供公共无参构造 public FirebaseLocation() {} public FirebaseLocation(double latitude, double longitude, long time) { this.latitude = latitude; this.longitude = longitude; this.time = time; } // 提供转为系统Location的方法 public Location toSystemLocation() { Location location = new Location("firebase"); location.setLatitude(this.latitude); location.setLongitude(this.longitude); location.setTime(this.time); // 其他字段按需赋值 return location; } // 必须提供对应字段的getter、setter public double getLatitude() { return latitude; } public void setLatitude(double latitude) { this.latitude = latitude; } public double getLongitude() { return longitude; } public void setLongitude(double longitude) { this.longitude = longitude; } public long getTime() { return time; } public void setTime(long time) { this.time = time; } }对应业务代码修改如下:
private void readChanges() { reference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { if(dataSnapshot.exists()){ FirebaseLocation firebaseLocation = dataSnapshot.getValue(FirebaseLocation.class); Location location = firebaseLocation.toSystemLocation(); // 后续使用location处理业务 } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // 建议添加错误处理逻辑 } }); }方案2:手动解析DataSnapshot数据构造Location实例
不需要额外定义类,适合存储的位置字段较少的场景,直接从快照中取值构造Location对象:private void readChanges() { reference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { if(dataSnapshot.exists()){ double lat = dataSnapshot.child("latitude").getValue(Double.class); double lng = dataSnapshot.child("longitude").getValue(Double.class); long time = dataSnapshot.child("time").getValue(Long.class); // 手动构造Location实例 Location location = new Location("firebase"); location.setLatitude(lat); location.setLongitude(lng); location.setTime(time); // 其他字段按需取值赋值 } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { // 建议添加错误处理逻辑 } }); }额外配置:ProGuard混淆规则(如果开启了混淆)
避免自定义的序列化类的无参构造和字段被混淆剥离,将如下规则添加到proguard-rules.pro文件中:# 替换成你自己的DTO类实际包路径 -keep class com.example.coffeebakeryfordriver.bean.FirebaseLocation { *; }
内容的提问来源于stack exchange,提问作者Vĩnh Trường Đặng
相关产品推荐
相关产品推荐

