有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Firebase实时数据库(AndroidJava)“类不定义noargument构造函数”

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

我可以很好地获取JSON字符串。当我尝试反序列化数据时,问题就开始了

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

关键是我已经定义了一个无参数构造函数。我也检查了这里的文件https://firebase.google.com/docs/database/安卓/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.63125262-25262/com。实例purinasa W/datosdb:DataSnapshot{key=1,value={phone=123456789,name=Mike} 2021-07-12 00:58:01.63725262-25262/com。实例purinasa W/datosdb:解析失败 通用域名格式。谷歌。火力基地。数据库DatabaseException:类com。实例美国国家航空航天局。应用数据库DataBaseHelper$TestData未定义无参数构造函数。如果您使用的是ProGuard,请确保这些构造函数没有被剥离。 在com上。谷歌。火力基地。数据库果心公用事业编码。CustomClassMapper$BeanMapper。反序列化(CustomClassMapper.java:570) 在com上。谷歌。火力基地。数据库果心公用事业编码。CustomClassMapper$BeanMapper。反序列化(CustomClassMapper.java:563) 在com上。谷歌。火力基地。数据库果心公用事业编码。自定义类映射器。convertBean(CustomClassMapper.java:433) 在com上。谷歌。火力基地。数据库果心公用事业编码。自定义类映射器。反序列化类(CustomClassMapper.java:232) 在com上。谷歌。火力基地。数据库果心公用事业编码。自定义类映射器。convertToCustomClass(CustomClassMapper.java:80) 在com上。谷歌。火力基地。数据库数据快照。getValue(DataSnapshot.java:203) 在com上。实例美国国家航空航天局。应用数据库数据库助手1美元。onDataChange(DataBaseHelper.java:33) 在com上。谷歌。火力基地。数据库果心ValueEventRegistration。fireEvent(ValueEventRegistration.java:75) 在com上。谷歌。火力基地。数据库果心看法数据事件。fire(DataEvent.java:63) 在com上。谷歌。火力基地。数据库果心看法EventRaiser 1美元。运行(EventRaiser.java:55) 在安卓。操作系统。汉德勒。handleCallback(Handler.java:938) 在安卓。操作系统。汉德勒。dispatchMessage(Handler.java:99) 在安卓。操作系统。活套。loop(Looper.java:223) 在安卓。应用程序。活动线程。main(ActivityThread.java:7656) 在爪哇。朗,反思一下。方法调用(本机方法) 在com上。安卓内部的操作系统。RuntimeInit$MethodAndArgsCaller。run(RuntimeInit.java:592) 在com上。安卓内部的操作系统。合子体。main(ZygoteInit.java:947)

更新:

在使用@Ticherhaz FreePalstan进行了一些测试之后,我们使用以下几行代码分别对数据进行了反序列化:

 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);

顺便说一句,我找不到一种方法来使用另一个代码而不引发异常


共 (2) 个答案

  1. # 1 楼答案

    最后,它将TestData用作一个独立的类,而不是一个内部类。我制作了一个新文件TestData。java并将其代码转移到了那里

    最后,数据库助手厕所是这样的:

    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. # 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;
        }
    }