【问题标题】:Wait for async call to finish execution with Android LiveData等待异步调用完成 Android LiveData 的执行
【发布时间】:2020-03-11 20:21:54
【问题描述】:

我正在使用 MVVM 架构开发一个 Android 应用。这是从我的存储库中返回 MutableLiveData 的函数,可以从 ViewModel 中观察到。

    public MutableLiveData<ArrayList<CoffeeShop>> getCoffeeShops(){
        setCoffeeShops();
        MutableLiveData<ArrayList<CoffeeShop>> data = new MutableLiveData<>();
        data.setValue(coffeeShops);
        return data;
    }

    public void setCoffeeShops() {
        CollectionReference coffeeShopsRef = database.collection("coffee_shops");
        coffeeShopsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>(){
            @Override
            public void onComplete(@NonNull Task< QuerySnapshot > task) {
                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        CoffeeShop coffeeShop = new CoffeeShop();
                        coffeeShop.setName((String) document.get("name"));
                        coffeeShop.setLocation((GeoPoint) document.get("location"));
                        coffeeShop.setOffers((ArrayList<String>) document.get("offers"));
                        coffeeShop.setRating((Long) document.get("rating"));
                        coffeeShop.setReviews((ArrayList<Review>) document.get("reviews"));
                        coffeeShops.add(coffeeShop);
                    }
                }
            }
        });
    }

setCoffeeShops() 函数对数据库执行异步调用并设置 coffeeShops 变量的值。我需要找到一种方法来等待异步调用得到解决,然后才将值分配给 MutableLiveData 对象。这是解决问题的正确方法吗?如果是,您会推荐什么?

谢谢!

【问题讨论】:

  • 您可以查看this

标签: android firebase android-livedata android-mvvm


【解决方案1】:

试试这个:

将回调参数设置为 setCoffeeShops()

例如:setCoffeeShops(Runnable callback)

当你设置的咖啡店完成后,调用回调:

callback.run()

当你调用 setCoffeeShops 时,这样做:

MutableLiveData<ArrayList<CoffeeShop>> data = new MutableLiveData<>();
setCoffeeShops(()->{  
    data.setValue(coffeeShops);
});
return data;

或者为了让你的代码更简洁,使用接口而不是像这样将coffeeShops 保留为全局变量:

    interface CoffeeShopLoader {
        void shopsLoaded(List<CoffeeShop> shops);
    }

    void setCoffeeShops(CoffeeShopLoader loader)  {
        ...

        loader.shopsLoaded(coffeeShops);
    }

    ... // and call it like this

       setCoffeeShops((shops)->{
           data.setValue(shops)
       });

    ...

【讨论】:

    【解决方案2】:

    我想推荐Room 数据库框架。它支持Livedata 并且还具有出色的 ORMapper。因此,通过简单的对象模型,您可以达到目标并减少代码以达到目标。

    以下链接向您展示了这样做的好方法:

    https://codelabs.developers.google.com/codelabs/android-training-livedata-viewmodel/#6

    但是,如果您没有任何迁移到 Room 的计划,只需将您的喜欢更改如下:

        public MutableLiveData<ArrayList<CoffeeShop>> getCoffeeShops(){
            MutableLiveData<ArrayList<CoffeeShop>> data = new MutableLiveData<>();
            setCoffeeShops(data);
            return data;
        }
    
        public void setCoffeeShops(MutableLiveData<ArrayList<CoffeeShop>> data) {
            CollectionReference coffeeShopsRef = database.collection("coffee_shops");
            coffeeShopsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>(){
                @Override
                public void onComplete(@NonNull Task< QuerySnapshot > task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            CoffeeShop coffeeShop = new CoffeeShop();
                            /* data conversion code*/
                            coffeeShops.add(coffeeShop);
                        }
    
                        //If runs on main thread 
                        data.setValue(coffeeShops)
    
                        //Otherwise
                        data.postValue(coffeeShops) 
    
                        //Use one of top lines base on the situation
                    }
                }
            });
        }
    

    现在您无需等待收集数据,只要在侦听器方法中准备好数据,更改就会被投射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 2019-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-04
      相关资源
      最近更新 更多