Java Android Firebase检索同步数据和;“返回”;信息技术

Java Android Firebase检索同步数据和;“返回”;信息技术,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我很抱歉,如果这看起来像一个愚蠢的问题,但我没有发现任何类似的问题,所以这里继续 我有一个类DatabaseService,用于从Firebase实时数据库检索数据(动物)。从上一篇文章中我了解到,因为这些API调用是异步的,所以应该创建一个接口来同步数据的检索(onDataChange()方法) 我的问题是: 为什么创建此接口并将其作为参数传递可以用于同步数据检索?在我的代码中,为什么调用接口的onCallBack方法(直到后来才定义)才能实现它,实现它的步骤是什么 创建了这个类作为数据库服务

我很抱歉,如果这看起来像一个愚蠢的问题,但我没有发现任何类似的问题,所以这里继续

我有一个类DatabaseService,用于从Firebase实时数据库检索数据(动物)。从上一篇文章中我了解到,因为这些API调用是异步的,所以应该创建一个接口来同步数据的检索(onDataChange()方法)

我的问题是:

  • 为什么创建此接口并将其作为参数传递可以用于同步数据检索?在我的代码中,为什么调用接口的onCallBack方法(直到后来才定义)才能实现它,实现它的步骤是什么
  • 创建了这个类作为数据库服务(因此得名),我希望它为包含这个服务的活动MyAnimalsActivity返回一个动物列表(list),以便生成一个RecyclerView。有没有办法把这个接口方法中的“void”改成“List”这样的东西

    List<Animal> listAnimals = databaseService.readData(); 
    
    List listAnimals=databaseService.readData();
    
    还是应该删除并删除整个DatabaseService类 在MyAnimalsActivity本身中添加其代码,以便在onDataChange()方法的全局列表中添加动物对象

  • 数据库服务:

    public class DatabaseService {
    
        private FirebaseDatabase firebaseDatabase;
        private DatabaseReference firebaseRootRef;
        private DatabaseReference animalsRef;
        List<Animal> animalsList;
    
        public DatabaseService() {
    
            this.firebaseDatabase = FirebaseDatabase.getInstance();
            this.firebaseRootRef = firebaseDatabase.getReference();
            this.animalsRef = firebaseDatabase.getReference("animals");
    
            animalsList = new ArrayList<>();
        }
    
    
        private interface FirebaseCallback {
            void onCallback(List<Animal> list);
        }
    
        public void readItemsFromDatabase(final FirebaseCallback firebaseCallback) {
    
            ValueEventListener valueEventListener = new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    animalsList.clear();
    
                    //dataSnapshot.getChildren() ---> iterate through entire dataSnapshot Object, to get the items names
                    for(DataSnapshot ds : dataSnapshot.getChildren()) {
                        Animal animal;
                        animal = ds.getValue(Animal.class);
                        animalsList.add(animal);
                    }
    
                    firebaseCallback.onCallback(animalsList);
    
                }
    
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Log.d("DATABASE_TAG", databaseError.getMessage());
                }
            };
    
            animalsRef.addValueEventListener(valueEventListener);
    
        }
    
    
        public void readData() {
            readItemsFromDatabase(new FirebaseCallback() {
                @Override
                public void onCallback(List<Animal> list) {
                    Log.d("DATABASE_TAG", list.toString());
                }
            });
        }
    
    }
    
    公共类数据库服务{
    私有FirebaseDatabase FirebaseDatabase;
    私有数据库引用firebaseRootRef;
    私有数据库参考AnimalRef;
    动物名录;
    公共数据库服务(){
    this.firebaseDatabase=firebaseDatabase.getInstance();
    this.firebaseRootRef=firebaseDatabase.getReference();
    this.animalsRef=firebaseDatabase.getReference(“动物”);
    animalsList=newarraylist();
    }
    私有接口FirebaseCallback{
    一次回拨无效(列表);
    }
    public void readItemsFromDatabase(最终FirebaseCallback FirebaseCallback){
    ValueEventListener ValueEventListener=新的ValueEventListener(){
    @凌驾
    public void onDataChange(@NonNull DataSnapshot DataSnapshot){
    animalsList.clear();
    //dataSnapshot.getChildren()-->遍历整个dataSnapshot对象,以获取项目名称
    对于(DataSnapshot ds:DataSnapshot.getChildren()){
    动物;
    animal=ds.getValue(animal.class);
    动物列表。添加(动物);
    }
    firebaseCallback.onCallback(animalsList);
    }
    @凌驾
    已取消的公共void(@NonNull DatabaseError DatabaseError){
    Log.d(“DATABASE_标记”,databaseError.getMessage());
    }
    };
    animalsRef.addValueEventListener(valueEventListener);
    }
    public void readData(){
    readItemsFromDatabase(新的FirebaseCallback(){
    @凌驾
    公开作废回拨(列表){
    Log.d(“DATABASE_标记”,list.toString());
    }
    });
    }
    }
    
    我的动物活动:

    public class MyAnimalsActivity extends AppCompatActivity {
    
    private RecyclerView recyclerView;
    private RecyclerView.Adapter animalAdapter;
    
    private List<Animal> listAnimals;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_animals);
    
        DatabaseService databaseService = new DatabaseService();
        databaseService.readData();
    
    
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true); //every item of the recyclerview has a fixed size;
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    
        listAnimals = new ArrayList<>();
        //listAnimals  =  databaseService.readData();  ??
    
    
    }
    }
    
    公共类MyAnimalsActivity扩展了AppCompatActivity{
    私人回收站;
    私有回收视图。适配器animalAdapter;
    私人动物名录;
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\u my\u animals);
    DatabaseService DatabaseService=新的DatabaseService();
    databaseService.readData();
    recyclerView=(recyclerView)findViewById(R.id.recyclerView);
    setHasFixedSize(true);//recyclerView的每个项都有一个固定的大小;
    recyclerView.setLayoutManager(新的LinearLayoutManager(本));
    listAnimals=新的ArrayList();
    //listAnimals=databaseService.readData()??
    }
    }
    
    编写一个返回异步值的方法(该值可能不存在)可能会导致空指针,如果您在它有数据之前调用它

    为了简单起见,由于方法
    readItemsFromDatabase
    是公共的,因此您可以从
    myanimalactivity
    调用它并从中获取数据

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_animals);
    
        DatabaseService databaseService = new DatabaseService();
        databaseService.readItemsFromDatabase(new DatabaseService.FirebaseCallback() {
                @Override
                public void onCallback(List<Animal> list) {
                    Log.d("DATABASE_TAG", list.toString());
    
                }
            });
    ...
    
    @覆盖
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\u my\u animals);
    DatabaseService DatabaseService=新的DatabaseService();
    databaseService.readItemsFromDatabase(新的databaseService.FirebaseCallback(){
    @凌驾
    公开作废回拨(列表){
    Log.d(“DATABASE_标记”,list.toString());
    }
    });
    ...
    

    我已将您的问题与我的一个项目隔离开来,它正在工作;此外,您可以检查MVP模式,它将为您解决所有这些问题,您的代码将变得更干净。

    编写一个返回异步值的方法,如果您在该方法有数据之前调用它,则可能会导致空指针

    为了简单起见,由于方法
    readItemsFromDatabase
    是公共的,因此您可以从
    myanimalactivity
    调用它并从中获取数据

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_animals);
    
        DatabaseService databaseService = new DatabaseService();
        databaseService.readItemsFromDatabase(new DatabaseService.FirebaseCallback() {
                @Override
                public void onCallback(List<Animal> list) {
                    Log.d("DATABASE_TAG", list.toString());
    
                }
            });
    ...
    
    @覆盖
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\u my\u animals);
    DatabaseService DatabaseService=新的DatabaseService();
    databaseService.readItemsFromDatabase(新的databaseService.FirebaseCallback(){
    @凌驾
    公开作废回拨(列表){
    Log.d(“DATABASE_标记”,list.toString());
    }
    });
    ...
    

    我已经将您的问题与我的一个项目隔离开来,它正在工作;此外,您可以检查MVP模式,它将为您解决所有这些问题,您的代码将变得更干净。

    谢谢您,但在按照您的建议编写之后,数据库方法“onCallBack”将不再同步