【问题标题】:Android Firebase Retrieving Data Synchronized and "returning" itAndroid Firebase 检索同步的数据并“返回”它
【发布时间】:2019-03-03 06:52:45
【问题描述】:

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

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

我的问题是:

  1. 为什么创建此接口并将其作为参数传递以用于同步数据检索?在我的代码中,为什么调用接口的方法 onCallBack(直到后来才定义)才能实现,实现它的步骤是什么?
  2. 已将此类创建为数据库服务(因此得名),我希望它返回包含此服务的 Activity 的动物列表 ( List ) MyAnimalsActivity ,以便创建 RecyclerView。有什么办法可以将此接口方法中的“void”更改为“List”以具有类似

    List<Animal> 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());
            }
        });
    }

}

我的动物活动:

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


}
}

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    编写一个返回可能不存在的异步值的方法,如果您在它拥有数据之前调用它可能会导致 NullPointers。

    为了简单起见,由于方法 readItemsFromDatabase 是公开的,您可以从您的 MyAnimalsActivity 调用它并从那里获取您的数据。

    @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());
    
                }
            });
    ...
    

    我已将您的问题与我的一个项目隔离开来,并且它正在运行;此外,您可以查看 MVP 模式,该模式将为您解决所有这些问题,您的代码将变得更简洁。

    【讨论】:

    • 谢谢,但是按照您的建议编写后,数据库方法“onCallBack”不再同步。有什么具体的我应该做的吗? prntscr.com/mqpd61
    • 据我了解,readItemsFromDatabase(..) 仍然没有同步,所以我修复它的方法是将相关代码(例如 RecyclerView)移动到它的 onCallBack 方法中。
    • 是的,你需要在回调中移动它,因为你不知道它什么时候完成
    • 您的列表将在回调结束时设置,因此您不能保证您的列表在 Activity 开始时已填充数据
    猜你喜欢
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    相关资源
    最近更新 更多