【问题标题】:NullPointerException when using MediatorLiveData使用 MediatorLiveData 时出现 NullPointerException
【发布时间】:2022-01-19 18:13:45
【问题描述】:

我想显示一个可排序的餐厅列表。当我使用简单的 LiveData 时它可以工作,但我得到了 NullPointerException,因为我将它更改为 mediatorLiveData。

在片段中,我使用这些行来观察 mediatorLiveData

vm.getAllRestaurantsWithOrderMediatorLD().observe(getViewLifecycleOwner(), listRestaurants -> {
            datas.clear();
            datas.addAll(listRestaurants);
            adapter.notifyDataSetChanged();
        });

这里是视图模型类:

public class ListRestaurantsViewModel extends ViewModel {

    private final RestaurantRepository restaurantRepository;
    private final SortRepository sortRepository;
    private final MutableLiveData<List<RestaurantViewState>> allRestaurantsViewStateLD = new MutableLiveData<>();
    private final MutableLiveData<SortRepository.OrderBy> orderLiveData = new MutableLiveData<>();
    private final MediatorLiveData<List<RestaurantViewState>> allRestaurantsWithOrderMediatorLD;

    Context ctx;

    public ListRestaurantsViewModel(RestaurantRepository restaurantRepository, SortRepository sortRepository, Context ctx) {
        this.ctx = ctx;
        this.restaurantRepository = restaurantRepository;
        this.sortRepository = sortRepository;

        allRestaurantsWithOrderMediatorLD = new MediatorLiveData<>();
        allRestaurantsWithOrderMediatorLD.addSource(getAllRestaurantsViewStateLD(), value -> allRestaurantsWithOrderMediatorLD.setValue(value));

        allRestaurantsWithOrderMediatorLD.addSource(getOrderLiveData(), order -> {
                                                       
                      List<RestaurantViewState> restaurants = getAllRestaurantsViewStateLD().getValue();
                      if (restaurants != null && !restaurants.isEmpty()) {
                      List<RestaurantViewState> newList = new ArrayList<>();
                      if (order == SortRepository.OrderBy.DISTANCE)
                                                                newList =
                                                                        Stream.of(restaurants).sorted((a, b) -> a.getDistance() - b.getDistance()).toList();

                     else if (order == SortRepository.OrderBy.RATING)
                                                                newList = Stream.of(restaurants).sorted((a, b) -> Double.compare(a.getStarsCount(),
                                                                                                                                 b.getStarsCount())).toList();

         allRestaurantsWithOrderMediatorLD.setValue(newList);
        }
    }
);
    }

    public MediatorLiveData<List<RestaurantViewState>> getAllRestaurantsWithOrderMediatorLD() {
        return allRestaurantsWithOrderMediatorLD;
    }

    public LiveData<SortRepository.OrderBy> getOrderLiveData() {
        return sortRepository.getOrderLiveData();
    }

    public LiveData<List<RestaurantViewState>> getAllRestaurantsViewStateLD() {
        return Transformations.map(restaurantRepository.getRestaurantsLiveData(), restaurantsList -> {
            List<RestaurantViewState> restaurantViewStates = new ArrayList<>();
            for (Restaurant r : restaurantsList) {

                restaurantViewStates.add(new RestaurantViewState(
                                                 r.getId(),
                                                 r.getName(),
                                                 r.getType(),
                                                 r.getAdress(),
                                                 r.getImage()
                                         )
                                        );
            }
            return restaurantViewStates;
        });
    }

这是错误,我明白了 java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observeForever(androidx.lifecycle.Observer)' on a null object reference

如果我观察片段中的 livedata getAllRestaurantsViewStateLD() 没有错误,所以我认为我在使用 mediatorLiveData 时没有得到任何东西 你看出来是什么了吗?

【问题讨论】:

    标签: java android nullpointerexception mediatorlivedata


    【解决方案1】:

    调用observeForever 时发生崩溃,但您的代码 sn-p 并未显示您正在使用它。所以问题出在其他地方。

    【讨论】:

    • 我不确定 observeForever 是什么。我不在任何地方使用它。
    • AFAIK observeForever 由中介实时数据在内部调用,如果 OP 发布了他的异常堆栈而不是单独的错误消息,那么也许可以确定他自己的代码的哪一行触发了它。
    • 错误信息中提到的那一行与MediatorLiveData.java中的void plug() { mLiveData.observeForever(this); }这个函数有关
    • @Emmcy 在这种情况下mLiveData 为空。试着理解为什么会这样。
    • 对我来说似乎很奇怪的是,它可以与它的一个来源一起工作(如果我观察到第一个 LiveData 就不会崩溃)。如果 mediatorLiveData 的来源不是,我不明白它如何为空
    猜你喜欢
    • 2013-12-29
    • 2013-12-19
    • 2013-04-13
    • 2014-11-11
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多