Android N 指纹识别 NullPointerException: Attempt toFragment.mNextAnim 的错误

修复FingerprintSettings中的NPE
本文记录了一次解决FingerprintSettings中出现的NullPointerException问题的过程。通过调整commit方法为commitAllowingStateLoss(),成功避免了在Activity状态保存后添加Fragment所导致的异常。

测试报的bug是这样的:

已录制指纹,关闭指纹后重新开启指纹识别,设置停止运行

步骤如下:

A)Preconditions:
已添加指纹
B)Operation step:
1.设置》安全》锁屏方式》滑动解锁
2.安全》指纹》设置备用解锁方式
Expect resut:
可以正常进入指纹管理界面
DTest result:
提示设置停止运行

log上报的错误是这样的:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
    at com.android.settings.fingerprint.FingerprintSettings$FingerprintSettingsFragment.updateAddPreference(FingerprintSettings.java:374)
    at com.android.settings.fingerprint.FingerprintSettings$FingerprintSettingsFragment.-wrap4(FingerprintSettings.java)
    at com.android.settings.fingerprint.FingerprintSettings$FingerprintSettingsFragment$3.handleMessage(FingerprintSettings.java:212)       

这是最初报的bug
以后上面的莫名其妙不怎么报了,但是下面这个bug必报

java.lang.NullPointerException: Attempt to write to field 'int android.app.Fragment.mNextAnim' on a null object reference

去网上搜了半天说是因为fragment为空的时候hide remove 或是show了,但是这毕竟是谷歌大神写的源码,毫无为空的地方
因为它也不显示到底第几行报错,所以一度让人很头疼

后来我们老大给我说是这个原因

Like commit() but allows the commit to be executed after an activity’s state is saved. This is dangerous because the commit can be lost if the activity needs to later be restored from its state, so this should only be used for cases where it is okay for the UI state to change unexpectedly on the user.

大致意思是说我使用的 commit方法是在Activity的onSaveInstanceState()之后调用的,这样会出错,因为

onSaveInstanceState方法是在该Activity即将被销毁前调用,来保存Activity数据的如果在保存完状态后

再给它添加Fragment就会出错。

解决办法就是把commit()方法替换成 commitAllowingStateLoss()就行了,其效果是一样的。

后来我将Setting中的所有commit()换成commitAllowingStateLoss()就好了
### Java中NullPointerException的解决方案 `java.lang.NullPointerException` 是一种运行时异常,通常发生在尝试访问或操作一个为 `null` 的对象时。根据引用内容[^2],将 `null` 参数传递给任何类或接口的构造函数或方法会导致抛出 `NullPointerException`。此外,使用包含 `null` 元素的数组或集合调用方法也可能引发该异常。 在尝试从空数组读取数据时,`NullPointerException` 可能出现的原因包括以下几种情况: 1. 数组本身为 `null`。 2. 尝试访问数组中的某个元素,但该元素值为 `null`。 以下是解决该问题的具体方法: #### 1. 检查数组是否为 `null` 在访问数组之前,应始终检查数组是否为 `null`。可以通过条件语句来确保数组已被正确初始化。 ```java if (array != null) { for (Object item : array) { if (item != null) { // 安全地操作非空元素 System.out.println(item.toString()); } else { System.out.println("Element is null"); } } } else { System.out.println("Array is null"); } ``` #### 2. 初始化数组 确保数组在使用前已被正确初始化。如果数组未被显式初始化,则其默认值可能为 `null`,从而导致 `NullPointerException`。 ```java Object[] array = new Object[5]; // 初始化数组 Arrays.fill(array, new Object()); // 填充数组以避免空元素 ``` #### 3. 使用默认值处理空元素 如果数组中可能存在 `null` 元素,可以在访问元素时提供默认值以避免异常。 ```java String[] strings = {"a", "b", null, "d"}; for (String str : strings) { System.out.println(str == null ? "Default Value" : str); } ``` #### 4. 使用流式操作(Java 8+) 利用 Java 8 中的 `Stream` API 和 `Optional` 类,可以更优雅地处理可能为空的数组或元素。 ```java import java.util.Optional; import java.util.stream.Stream; public class Example { public static void main(String[] args) { String[] array = {"a", "b", null, "d"}; Stream.of(Optional.ofNullable(array).orElse(new String[0])) .flatMap(Stream::of) .filter(Objects::nonNull) .forEach(System.out::println); } } ``` 上述代码通过 `Optional.ofNullable` 确保即使数组为 `null`,也不会抛出异常,并且过滤掉所有为 `null` 的元素。 #### 5. 调试与日志记录 在实际开发中,建议通过调试工具或日志记录来定位问题的根本原因。例如,打印堆栈信息可以帮助快速找到异常发生的位置。 ```java try { Object obj = null; System.out.println(obj.toString()); } catch (NullPointerException e) { e.printStackTrace(); } ``` --- ### 总结 `NullPointerException` 是 Java 开发中常见的运行时异常。为了防止该异常的发生,需要对可能为 `null` 的对象进行检查,并确保在访问数组或其他集合类型的数据时,它们已被正确初始化。此外,利用现代 Java 特性如 `Optional` 和 `Stream`,可以进一步提高代码的安全性和可读性[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值