I get crashes for my application. Basically, I have a fragment in which the dialogue should be displayed in one scenario. I created a dialogue by expanding a portion of the dialogue. The problem is that some users throw a null pointer exception throw. This is a snippet of dialogue:
VerifyOTPDialog verifyOTPDialog = VerifyOTPDialog.newInstance("Kindly Enter the OTP sent to your Registered Mobile No. :", false, "Verify & Proceed", "home_screen"); verifyOTPDialog.show(getFragmentManager(), VerifyOTPDialog.class.getSimpleName());
The application crashes in the second line. From crashlytics, I got the following stack trace:
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.FragmentTransaction android.app.FragmentManager.beginTransaction()' on a null object reference at android.app.DialogFragment.show(DialogFragment.java:228) at in.droom.fragments.HomeScreenFragment.updateUI(HomeScreenFragment.java:553) at in.droom.fragments.HomeScreenFragment.onResponse(HomeScreenFragment.java:626) at in.droom.fragments.HomeScreenFragment.onResponse(HomeScreenFragment.java:100) at in.droom.util.DroomApi$1.onPostExecute(DroomApi.java:1136) at in.droom.util.DroomApi$1.onPostExecute(DroomApi.java:1094) at android.os.AsyncTask.finish(AsyncTask.java:636) at android.os.AsyncTask.access$500(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5637) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
0. Crashed: main: 0 0 0x0000000000000000
at android.app.DialogFragment.show(DialogFragment.java:228) at in.droom.fragments.HomeScreenFragment.updateUI(HomeScreenFragment.java:553) at in.droom.fragments.HomeScreenFragment.onResponse(HomeScreenFragment.java:626) at in.droom.fragments.HomeScreenFragment.onResponse(HomeScreenFragment.java:100) at in.droom.util.DroomApi$1.onPostExecute(DroomApi.java:1136) at in.droom.util.DroomApi$1.onPostExecute(DroomApi.java:1094) at android.os.AsyncTask.finish(AsyncTask.java:636) at android.os.AsyncTask.access$500(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5637) at java.lang.reflect.Method.invoke(Method.java) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
As I understand it, the fragment manager at some point in time became zero. But I can not reproduce the script. Failures happen with no. users almost every day.
Update: (VerifyOtpDialog)
public class VerifyOTPDialog extends DialogFragment implements OnClickListener { private static final String TAG_NAME = VerifyOTPDialog.class.getSimpleName(); private Context ctx; private Dialog dialog; private boolean isLaterVisible; private String strTitle, strBtnTitle, strFragment = ""; private BroadcastReceiver broadcastReceiver; private ProfileAddressContactInfoModel userModel; private VerifyOTPDialogDismissed verifyOTPDialogDismissed; public static final String RECEIVE_OTP = "com.myapp.ACTION_RECEIVED"; private ImageView imgViewForClose; private RobotoRegularEditTextView editTextForOTP; private RobotoBoldTextView btnLater, btnVerifyAndProceed; private RobotoLightTextView txtViewForTitle, txtViewForResendOTP; public popFragmentListener mPopFragmentListener; public VerifyOTPDialog() { } public static VerifyOTPDialog newInstance(String strTitle, boolean isLaterVisible, String strBtnTitle, String strFragment) { VerifyOTPDialog dialog = new VerifyOTPDialog(); Bundle b = new Bundle(); b.putString("title", strTitle); b.putBoolean("isLaterVisible", isLaterVisible); b.putString("btnTitle", strBtnTitle); b.putString("strFrom", strFragment); dialog.setArguments(b); return dialog; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ctx = getActivity(); registerReceiver(); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { dialog = super.onCreateDialog(savedInstanceState); dialog.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(android.content.DialogInterface dialog, int keyCode, android.view.KeyEvent event) { if ((keyCode == android.view.KeyEvent.KEYCODE_BACK)) { AppUtil.hideKeyboard(); return true; } else return false; } }); return dialog; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.verify_otp_popup, container, false); Bundle b = getArguments(); strTitle = b.getString("title"); isLaterVisible = b.getBoolean("isLaterVisible"); strBtnTitle = b.getString("btnTitle"); strFragment = b.getString("strFrom"); getDialog().setCanceledOnTouchOutside(false); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(0)); userModel = AppUtil.getUserProfile(); imgViewForClose = (ImageView) view.findViewById(R.id.imgViewForClose); editTextForOTP = (RobotoRegularEditTextView) view.findViewById(R.id.editTextForOTP); btnLater = (RobotoBoldTextView) view.findViewById(R.id.btnLater); btnVerifyAndProceed = (RobotoBoldTextView) view.findViewById(R.id.btnVerifyAndProceed); txtViewForTitle = (RobotoLightTextView) view.findViewById(R.id.txtViewForTitle); txtViewForResendOTP = (RobotoLightTextView) view.findViewById(R.id.txtViewForResendOTP); if (userModel != null) txtViewForTitle.setText(strTitle + " +91 " + userModel.getContactInfo().getMobilePhone()); txtViewForResendOTP.setText(getUnderlinedContent()); if (!isLaterVisible) btnLater.setVisibility(View.GONE); btnVerifyAndProceed.setText(strBtnTitle); imgViewForClose.setOnClickListener(this); txtViewForResendOTP.setOnClickListener(this); btnLater.setOnClickListener(this); btnVerifyAndProceed.setOnClickListener(this); return view; } public interface VerifyOTPDialogDismissed { void dialogDismissing(String... s); } @Override public void onDismiss(DialogInterface dialog) { super.onDismiss(dialog); } public VerifyOTPDialogDismissed getDialogDismissListener() { return verifyOTPDialogDismissed; } public void setDialogDismissListener(VerifyOTPDialogDismissed VerifyOTPDialogDismissed) { this.verifyOTPDialogDismissed = VerifyOTPDialogDismissed; } private void registerReceiver() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(RECEIVE_OTP); broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String strOTP = intent.getExtras().getString("otp"); if (strOTP != null && editTextForOTP != null) editTextForOTP.setText(strOTP); } }; ctx.registerReceiver(broadcastReceiver, intentFilter); } private SpannableString getUnderlinedContent() { SpannableString content = new SpannableString(getResources().getString(R.string.resend_otp)); content.setSpan(new UnderlineSpan(), 0, content.length(), 0); content.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.blue_button)), 0, content.length(), 0); return content; } private void sendOTP(HashMap<String, String> params) { Response.Listener<JSONObject> responseListener = new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { Logger.debugMessage("Response Object", response.toString()); String responseCode = response.getString("code"); if (responseCode.equalsIgnoreCase("success")) { String message = response.getString("message"); Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show(); } else if (responseCode.equalsIgnoreCase("failed")) { if (response.has("error")) { if (response.has("error_code")) { String error_code = response.optString("error_code"); displayMessageAlert(response.optString("error"), "", error_code); } else { displayMessageAlert(response.optString("error"), "", ""); } } else if (response.has("errors")) { JSONArray errorsArray; try { errorsArray = response.getJSONArray("errors"); Toast.makeText(ctx, errorsArray.getString(0), Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } } } } catch (JSONException e) { e.printStackTrace(); } } }; Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }; Api.sendOTP(params, responseListener, errorListener); } private void verifyOTP(HashMap<String, String> params, final String strFragment) { Response.Listener<JSONObject> responseListener = new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { Logger.debugMessage("Response Object", response.toString()); String responseCode = response.getString("code"); if (responseCode.equalsIgnoreCase("success")) { if (userModel != null) { userModel.setPhoneVerified(true); userModel.setOTPVerified(true); AppUtil.saveUserProfile(userModel); } VerifyOTPDialog.this.dismissAllowingStateLoss(); String event_name = ""; if (strFragment.equalsIgnoreCase("SellFragment")) { event_name = "otp_verified_on_sell"; MainActivity.getInstance().pushFragment(SellFragment.newInstance(), SellFragment.class.getSimpleName(), true); } else if (strFragment.equalsIgnoreCase("QuickSellFragment")) { event_name = "otp_verified_on_quick_sell"; MainActivity.getInstance().pushFragment(new QuickSellFragment(), QuickSellFragment.class.getSimpleName(), true); } else if (strFragment.equalsIgnoreCase("gotoPaymentFlow")) { event_name = "otp_verified_on_payment"; DraftSummaryFragment.getInstance().gotoPaymentFlow(); } else if (strFragment.equalsIgnoreCase("gotoPlaceBidPage")) { event_name = "otp_verified_on_place_bid"; verifyOTPDialogDismissed.dialogDismissing(strFragment); } else if (strFragment.equalsIgnoreCase("make_best_offer")) { event_name = "otp_verified_on_make_best_offer"; verifyOTPDialogDismissed.dialogDismissing(strFragment); } else if (strFragment.equalsIgnoreCase("checkAvailableFees")) { event_name = "otp_verified_on_quick_sell"; QuickSellDraftSummaryFragment.getInstance().checkAvailableFees(); } else if (strFragment.equalsIgnoreCase("home_screen")) { event_name = "otp_verified_for_casual_seller"; } else if (strFragment.equalsIgnoreCase("my_profile")) { event_name = "otp_verified_from_my_profile"; } else if (strFragment.equalsIgnoreCase("my_profile")) { event_name = "otp_verified_from_my_profile"; } else if (strFragment.equalsIgnoreCase("pro_seller_profile_settings")) { event_name = "otp_verified_from_pro_seller_profile_settings"; } else if (strFragment.equalsIgnoreCase("pro_seller_welcome")) { event_name = "otp_verified_from_pro_seller_welcome"; } else if (strFragment.equalsIgnoreCase("seller_badges")) { event_name = "otp_verified_from_seller_badges"; } else if (strFragment.equalsIgnoreCase("trust_factor")) { event_name = "otp_verified_from_trust_factor"; } else if (strFragment.equalsIgnoreCase("ProSellerDashboard")) MainActivity.getInstance().pushFragment(ProSellerDashboardFragment.newInstance(false), ProSellerDashboardFragment.class.getSimpleName(), true); else event_name = "otp_verified_from_my_account"; JSONObject post = BetaOutAPIs.getPostDataForUserAdd(userModel, "update"); JSONArray eventArray = new JSONArray(); JSONObject event = new JSONObject(); event.put("name", event_name); event.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000)); eventArray.put(event); post.put("events", eventArray); BetaOutAPIs.sendEventToBetaOut(post, TAG_NAME); BaseApplication.getInstance().trackMoEngageEvents(event_name, new PayloadBuilder().build()); } else if (responseCode.equalsIgnoreCase("failed")) { btnVerifyAndProceed.setEnabled(true); if (response.has("error")) { if (response.has("error_code")) { String error_code = response.optString("error_code"); displayMessageAlert(response.optString("error"), "", error_code); } else { displayMessageAlert(response.optString("error"), "", ""); } } else if (response.has("errors")) { Toast.makeText(ctx, response.optString("errors"), Toast.LENGTH_SHORT).show(); } } } catch (JSONException e) { e.printStackTrace(); } } }; Response.ErrorListener errorListener = new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); } }; Api.verifyOTP(params, responseListener, errorListener); } private boolean validateOTP() { String validationMessage = ""; boolean isValid = true; String email = editTextForOTP.getText().toString(); if (email.length() == 0) { isValid = false; validationMessage = "Please Enter OTP"; Toast.makeText(getActivity(), validationMessage, Toast.LENGTH_SHORT).show(); } return isValid; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.imgViewForClose: VerifyOTPDialog.this.dismissAllowingStateLoss(); break; case R.id.txtViewForResendOTP: if (userModel != null) { HashMap<String, String> params = new HashMap<String, String>(); params.put("user_id", AppSharedPref.getUserId()); params.put("phone", userModel.getContactInfo().getMobilePhone()); sendOTP(params); } break; case R.id.btnLater: VerifyOTPDialog.this.dismissAllowingStateLoss(); if (mPopFragmentListener != null) mPopFragmentListener.gotoRootFragment(); if (strFragment.equalsIgnoreCase("SellFragment")) { MainActivity.getInstance().pushFragment(SellFragment.newInstance(), SellFragment.class.getSimpleName(), true); } else if (strFragment.equalsIgnoreCase("QuickSellFragment")) { MainActivity.getInstance().pushFragment(new QuickSellFragment(), QuickSellFragment.class.getSimpleName(), true); } else if (strFragment.equalsIgnoreCase("gotoPlaceBidPage")) {