使用 MediatorLiveData 时出现 NullPointerException
Posted
技术标签:
【中文标题】使用 MediatorLiveData 时出现 NullPointerException【英文标题】:NullPointerException when using MediatorLiveData 【发布时间】: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 时没有得到任何东西 你看出来是什么了吗?
【问题讨论】:
【参考方案1】:调用observeForever
时发生崩溃,但您的代码 sn-p 并未显示您正在使用它。所以问题出在其他地方。
【讨论】:
我不确定 observeForever 是什么。我不在任何地方使用它。 AFAIK observeForever 由中介实时数据在内部调用,如果 OP 发布了他的异常堆栈而不是单独的错误消息,那么也许可以确定他自己的代码的哪一行触发了它。 错误信息中提到的那一行与MediatorLiveData.java中的void plug() mLiveData.observeForever(this);
这个函数有关
@Emmcy 在这种情况下mLiveData
为空。试着理解为什么会这样。
对我来说似乎很奇怪的是,它可以与它的一个来源一起工作(如果我观察到第一个 LiveData 就不会崩溃)。如果 mediatorLiveData 的来源不是,我不明白它如何为空以上是关于使用 MediatorLiveData 时出现 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章
Jetpack之LiveData扩展MediatorLiveData
具有多个参数的 MediatorLiveData 或 switchMap 转换
使用 CASE WHEN 语句时出现 RODBC“无效字符\n”错误
数据绑定 - MediatorLiveData 未在 Fragment 内触发