使用Bundle在Fragment间传值时触发NullPointerException问题求助
解决Fragment间Bundle传值空指针异常
问题现象
出现空指针异常:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
相关代码
signupFragment 代码
public class signupFragment extends Fragment { private AutoCompleteTextView autoCompleteTextView; private EditText name,address,phone,alt_phone; private CountryCodePicker ccp; private ImageView user_dp; private Button signup_btn; private NavController navController; private Uri imageUri; public signupFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View layoutSignup= inflater.inflate(R.layout.fragment_signup, container, false); ((AppCompatActivity)getActivity()).getSupportActionBar().hide(); return layoutSignup; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); autoCompleteTextView = view.findViewById(R.id.auto_signup); name = view.findViewById(R.id.name_signup); address = view.findViewById(R.id.address_signup); phone = view.findViewById(R.id.phone_signup); alt_phone = view.findViewById(R.id.alt_phone_signup); ccp = view.findViewById(R.id.ccp_signup); user_dp = view.findViewById(R.id.img_signup); signup_btn = view.findViewById(R.id.btn_signup); navController = Navigation.findNavController(view); ccp.registerCarrierNumberEditText(phone); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), R.array.user_type, R.layout.dropdown_register); autoCompleteTextView.setAdapter(adapter); signup_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bundle bundle = new Bundle(); bundle.putString("name",name.getText().toString()); bundle.putString("phone",ccp.getFullNumberWithPlus().replace(" ","")); bundle.putString("user_type",autoCompleteTextView.getText().toString()); bundle.putString("alt_phone",alt_phone.getText().toString()); bundle.putString("address",address.getText().toString()); bundle.putString("dp_url",user_dp.getResources().toString()); otpFragment OtpFragment = new otpFragment(); OtpFragment.setArguments(bundle); getFragmentManager().beginTransaction().replace(R.id.fragmentContainerView2,OtpFragment).commit(); navController.navigate(R.id.action_signupFragment_to_otpFragment); } }); user_dp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { setimage(); } }); } // This is to select the image from the mobile private void setimage() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent,100); } // This is to set the image and to check if we got an image or not @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==100 && data!=null && data.getData()!=null){ imageUri = data.getData(); user_dp.setImageURI(imageUri); } } }
otpFragment 代码
public class otpFragment extends Fragment { private Button verify_otp_btn; private EditText edt_otp; private TextView resend_otp; private FirebaseAuth mAuth; private String dp_url=""; private String name=""; private String phoneNumber=""; private String otpid=""; private String user_type=""; private String user_id=""; private String alt_phone=""; private String address=""; private NavController navController; // firebase declaration private FirebaseFirestore firestore; public otpFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View layoutOtp= inflater.inflate(R.layout.fragment_otp, container, false); ((AppCompatActivity)getActivity()).getSupportActionBar().hide(); return layoutOtp; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); verify_otp_btn= view.findViewById(R.id.verify_otp_btn); edt_otp= view.findViewById(R.id.code_otp); resend_otp=view.findViewById(R.id.resend_otp); navController= Navigation.findNavController(view); Bundle result; result = this.getArguments(); name = result.getString("name"); phoneNumber = result.getString("phone"); user_type = result.getString("user_type"); alt_phone = result.getString("alt_phone"); address = result.getString("address"); dp_url = result.getString("dp_url"); Log.d("phone no",phoneNumber+" this is "); Log.d("phone no",name+" this is "); Log.d("phone no",user_type+" this is "); Log.d("phone no",alt_phone+" this is "); Log.d("phone no",address+" this is "); Log.d("phone no",dp_url+" this is "); verify_otp(); }
问题根源
你同时使用了Fragment事务和Navigation组件来跳转Fragment:
- 你创建了带Bundle的otpFragment实例并通过事务提交,但随后又调用了
navController.navigate(),这会创建一个全新的otpFragment实例(不带Bundle),覆盖之前的实例 - 最终显示的是Navigation创建的无Bundle实例,导致
getArguments()返回null,调用getString()时触发空指针异常
另外还有两个次要问题:
- 图片Uri获取错误:
user_dp.getResources().toString()无法获取选中的图片Uri,应该使用onActivityResult中赋值的imageUri - otpFragment中未做Bundle空判断,即使传值正常也可能因异常情况导致崩溃
解决方案
1. 移除冗余的Fragment事务代码,改用Navigation传递Bundle
修改signupFragment中点击事件的代码,删除Fragment事务相关代码,将Bundle作为参数传给navController.navigate():
signup_btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bundle bundle = new Bundle(); bundle.putString("name", name.getText().toString()); bundle.putString("phone", ccp.getFullNumberWithPlus().replace(" ", "")); bundle.putString("user_type", autoCompleteTextView.getText().toString()); bundle.putString("alt_phone", alt_phone.getText().toString()); bundle.putString("address", address.getText().toString()); // 修正图片Uri获取逻辑 bundle.putString("dp_url", imageUri != null ? imageUri.toString() : ""); // 移除以下三行冗余代码 // otpFragment OtpFragment = new otpFragment(); // OtpFragment.setArguments(bundle); // getFragmentManager().beginTransaction().replace(R.id.fragmentContainerView2,OtpFragment).commit(); // 使用Navigation传递Bundle跳转 navController.navigate(R.id.action_signupFragment_to_otpFragment, bundle); } });
2. 增加Bundle空指针防护
在otpFragment中先判断Bundle是否为null,避免空指针异常:
Bundle result = getArguments(); if (result != null) { name = result.getString("name", ""); phoneNumber = result.getString("phone", ""); user_type = result.getString("user_type", ""); alt_phone = result.getString("alt_phone", ""); address = result.getString("address", ""); dp_url = result.getString("dp_url", ""); }
3. 验证图片Uri传递正确性
确保imageUri在onActivityResult中正确赋值,并且传递时做非空判断,避免传递无效字符串。
内容的提问来源于stack exchange,提问作者zuni
相关产品推荐
相关产品推荐

