Android使用LiveData联动双Spinner触发onItemSelected空指针异常问题
问题成因
- 直接崩溃原因:你在
onItemSelected方法中将view参数声明为非空类型View,但Android Framework层调用该回调时,部分场景会传入null作为view参数,Kotlin空安全校验检测到非空参数收到null值,直接抛出空指针异常。 - 触发时机:给Spinner设置新的Adapter时,系统会自动触发一次
onItemSelected回调,你设置完监听后ViewModel返回数据填充第一个Spinner的Adapter,刚好触发了上述空参数问题。
解决方案
1. 修复参数空声明(必做)
将onItemSelected方法的view参数改为可空类型View?即可,你当前业务逻辑并未使用该参数,修改后不影响原有功能:
binding.inventoryAddEditProductGroupSpinner.onItemSelectedListener = object: AdapterView.OnItemSelectedListener{ // 把view参数改为View? override fun onItemSelected(parent:AdapterView<*>, view: View?, position: Int, id: Long){ val productGroupObject = parent.selectedItem as ProductGroupObject if (productGroupObject.productGroupID.isNotEmpty()){ businessViewModel.updateCurrentProductGroupVMLiveData(productGroupObject.productGroupID) } } override fun onNothingSelected(parent: AdapterView<*>){} }
2. 可选优化:过滤首次自动触发的回调
如果不需要Spinner首次填充数据时自动触发选中逻辑,可以加标记位跳过首次回调:
// Fragment内添加成员变量 private var isFirstGroupSelect = true // 回调内新增判断 override fun onItemSelected(parent:AdapterView<*>, view: View?, position: Int, id: Long){ if (isFirstGroupSelect) { isFirstGroupSelect = false return } // 原有业务逻辑不变 }
3. 可选隐患修复:避免ViewModel强转崩溃
你当前ViewModel中filter后的强转逻辑存在风险,若过滤结果为空会抛出类型转换异常,建议改为安全写法:
fun updateCurrentProductGroupVMLiveData (currentProductGroupId: String) { val newProductGroup = allAppDataProductGroups.value?.find { productGroup -> productGroup.productGroupID == currentProductGroupId } _currentProductGroup.value = newProductGroup if(newProductGroup?.productGroup != null) { // 修改为安全转换+空兜底 val filteredProductsList = allAppDataProductTypes.value ?.filter { productTypeObject -> productTypeObject.productGroup == newProductGroup.productGroup } ?.toMutableList() as? ArrayList<ProductTypeObject> ?: arrayListOf() _filteredAppDataProductTypes.value = filteredProductsList } Log.d(TAG, "updateCurrentProductGroupVMLiveData(): '_currentProductGroupId.value' updated ($currentProductGroupId)") }
内容的提问来源于stack exchange,提问作者Scamparelli
相关产品推荐
相关产品推荐

