我正在尝试使用捆绑包在活动及其片段之间传递数据。以下是我正在使用的代码:
活动:
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
,有时不是。
你的经历
在bundle
被null
的情况下,storeName = bundle.getString("xx");
行在试图调用bundle
null
getString("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
以及何时不返回。