bundle.containskey("xx") 返回 true,但系统抛出 NPE



我正在尝试使用捆绑包在活动及其片段之间传递数据。以下是我正在使用的代码:

活动:

Fragment newmaf = new Fragment();
Bundle args = new Bundle();
args.putString("xx",xx);
args.putString("yy",yy);
newmaf.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.view_pager,newmaf);
transaction.addToBackStack(null);
transaction.commit();

片段:

Bundle bundle = this.getArguments();
Log.d(tag,"bundle contents: "+bundle.toString() +" has xx: "+bundle.containsKey("xx"));
storeName = bundle.getString("xx");
dateOfPurchase = bundle.getString("yy");

问题是,虽然 bundle.tostring(( 和 bundle.containsKey("xx"( 分别向我显示我的数据并返回 TRUE,但我仍然收到以下错误消息:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.toString()' on a null object reference

日志语句的输出:

2020-01-28 22:43:05.988 23850-23850/com.example.sf_v000 D/MAF: bundle contents: Bundle[{xx=123, yy=123}] has xx: true

我无法解决这个问题。谁能在这里帮忙?

谢谢!

可能会发生什么

问题是有时你的bundle变量是null,有时不是。

你的经历

bundlenull的情况下,storeName = bundle.getString("xx");行在试图调用bundlenullgetString("xx")时抛出了一个NPE。

你可能误解了这个例外,认为getString()本身就有问题。然后,您添加了Log.d行,其中包括对bundle.toString()的调用。这会导致错误现在已经出现在bundle.toString()中,因为这个新代码行位于对bundle.getString("xx")的调用之上。

该方法可能被调用了两次。在第一次传递期间,getArguments()返回一个Bundle对象。对bundle.toString()bundle.getString("xx")的调用都按预期工作,导致Log.d打印出来以显示密钥"xx"确实在捆绑包中。在第二次传递时,getArguments()返回null,导致在调用bundle.toString()进行Log.d参数时发生 NPE。

也就是说:无论捆绑包中是否有任何特定键,都与您遇到的 NullPointerException 无关。尝试找出getArguments()何时以及为何返回null

如何修复

我建议将当前的Log.d行替换为Log.d(tag, "bundle is " + bundle);。这将允许您验证bundle变量是否null。您的 Logcat 输出很可能如下所示:

D/MAF: bundle is android.os.Bundle@f65ad1a3
D/MAF: bundle is null
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference

这将证明代码使用捆绑对象(第一行(传递一次,然后在没有捆绑对象(第二行(的情况下再次传递,这将导致在空引用(第三行(上调用第一个方法时发生 NPE。

然后,可以继续向行storeName = bundle.getString("xx");添加断点。在调试模式下运行应用,每次查看堆栈跟踪。这将帮助您了解getArguments()何时按预期返回Bundle以及何时不返回。

最新更新