【问题标题】:Firebase Realtime Database (Android-Java)- "Class does not define a no-argument constructor"Firebase 实时数据库(Android-Java)-“类未定义无参数构造函数”
【发布时间】:2021-09-21 05:08:32
【问题描述】:

我正在尝试从 Java Android 项目的 Firebase 实时数据库中读取数据。我正在使用 Android Studio 4.2.2。

我可以得到 JSON 字符串。当我尝试反序列化数据时,问题就开始了。

此时我得到一个异常:“没有定义无参数构造函数。如果您使用 ProGuard,请确保这些构造函数没有被剥离。”

关键是我已经定义了一个无参数的构造函数。我还检查了这里的文档https://firebase.google.com/docs/database/android/read-and-write

我的问题是:

  1. 我做错了什么?
  2. 如何解析具有多个级别的 JSON?
  3. 变量名是否必须与 JSON 的键名相同?

提前致谢!

JSON 看起来像这样:

Data Tree

在 Logcat 中,我可以看到 JSON 安全到达应用程序:

{ key = 1, value = {phone=123456789, name=Mike} }

这里有代码:

public class DataBaseHelper {

private DatabaseReference mDatabase;
public TestData result;

public DataBaseHelper() {
    mDatabase = FirebaseDatabase.getInstance().getReference();

    // Creamos query
    Query query = mDatabase.child("TestData");


    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                try {
                    Log.w("datosdb", userSnapshot.toString());
                    result = userSnapshot.getValue(TestData.class);

                } catch (Exception e) {
                    Log.w("datosdb", "Parse failed", e);
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // Getting Post failed, log a message
            Log.w("datosdb", "loadPost:onCancelled", databaseError.toException());
            // ...
        }
    });


}


public class TestData {
    public TestData() {
    }

    public String name;
    public int phone;

    public String getName() {
        return this.name;
    }

    public int getPhone() {
        return this.phone;
    }
}

}

这是一个例外:

2021-07-12 00:58:01.631 25262-25262/com.example.purinasa W/datosdb: DataSnapshot { key = 1, value = {phone=123456789, name=Mike} } 2021-07-12 00:58:01.637 25262-25262/com.example.purinasa W/datosdb:解析失败 com.google.firebase.database.DatabaseException:com.example.purinasa.application.dataBase.DataBaseHelper$TestData 类未定义无参数构造函数。如果您使用 ProGuard,请确保未剥离这些构造函数。 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:570) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80) 在 com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203) 在 com.example.purinasa.application.dataBase.DataBaseHelper$1.onDataChange(DataBaseHelper.java:33) 在 com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75) 在 com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63) 在 com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55) 在 android.os.Handler.handleCallback(Handler.java:938) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:223) 在 android.app.ActivityThread.main(ActivityThread.java:7656) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

更新:

在使用@Ticherhaz-FreePalestine 进行一些测试后,我们设法使用以下行单独反序列化数据:

 String name = userSnapshot.child("name").getValue(String.class);
                    Log.w("datosdb", "String is here!!!" + name);

                    long phone = userSnapshot.child("phone").getValue(Long.class);
                    Log.w("datosdb", "Long is here!!!" + phone);

顺便说一句,我找不到在不引发异常的情况下使用另一个代码的方法。

【问题讨论】:

    标签: java android firebase firebase-realtime-database android-studio-4.2


    【解决方案1】:

    最后,它通过使用 TestData 作为独立类而不是内部类来工作。我创建了一个新文件 TestData.java 并将其代码移到那里。

    所以最终 DatabaseHelper 像这样失去了:

    public class DatabaseHelper {
    
    private DatabaseReference mDatabase;
    TestData result;
    
    public DatabaseHelper() {
        mDatabase = FirebaseDatabase.getInstance().getReference();
    
        // We create a query
        Query query = mDatabase.child("TestData");
    
        //We recive query
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
                    Log.w("datosdb", "Tenemos el resultado de la query.");
                    try {
                        Log.w("datosdb", userSnapshot.toString());
    
                        // Deserializing only name
                        String name = userSnapshot.child("name").getValue(String.class);
                        Log.w("datosdb", "String is here!!!" + name);
    
                        // Deserializing only phone
                        long phone = userSnapshot.child("phone").getValue(Long.class);
                        Log.w("datosdb", "Long is here!!!" + phone);
    
                        // Deserializing into a TestData object
                        TestData result = userSnapshot.getValue(TestData.class);
                        Log.w("datosdb", "Parse success!!!");
    
                    } catch (Exception e) {
                        Log.w("datosdb", "Parse failed", e);
                    }
                }
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
                // Getting Post failed, log a message
                Log.w("datosdb", "loadPost:onCancelled", databaseError.toException());
                // ...
            }
        });
    
    
    }
    

    }

    TestData 看起来像这样(现在在它自己的 .java 文件中):

    public class TestData {
    private String name;
    private long phone;
    
    public TestData(){}
    
    public TestData(String name, long phone){
        this.name = name;
        this.phone = phone;
    }
    
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public long getPhone() {
        return this.phone;
    }
    
    public void setPhone(long phone) {
        this.phone = phone;
    }
    

    }

    【讨论】:

      【解决方案2】:

      你已经有一个空的构造函数。所以需要另一个具有所有属性的构造函数。

      @Keep
      public class TestData {
          private String name;
          private int phone;
      
          public TestData() {
          }
      
          public TestData(String name, int phone) {
              this.name = name;
              this.phone = phone;
          }
      
          public String getName() {
              return this.name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getPhone() {
              return this.phone;
          }
      
          public void setPhone(int phone) {
              this.phone = phone;
          }
      }
      

      【讨论】:

      • 感谢 Ticherhaz!对不起,我试过了,但问题没有解决。它不断抛出: com.example.purinasa.application.dataBase.DataBaseHelper$TestData 类没有定义无参数构造函数。如果您使用 ProGuard,请确保未剥离这些构造函数。
      • 您是否启用了 ProGuard? @Iroqas
      • 我没有。我是 Android Studio 的新手。是否默认启用?我正在检查它,但似乎不是...... ¿我如何检查它?
      • @Iroqas 我已经更新了答案。可以再试一次
      • 我猜 bould.gradle 的这行意味着它被禁用 buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' }跨度>
      猜你喜欢
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-12
      相关资源
      最近更新 更多