I am getting crashes for my app. Basically, I have a fragment in which a dialog has to be displayed in one scenario. I had created dialog by extending dialog fragment. The problem is for some users it crashes throwing null pointer exception. This is the snippet of dialog:
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 app crashes at the 2nd 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 far as I understood, the fragment manager became null at some point of time. But, I am unable to reproduce the scenario. The crashes are happening to no. of users almost everyday.
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")) {
//verifyOTPDialogDismissed.dialogDismissing();
} else if (strFragment.equalsIgnoreCase("ProSellerDashboard"))
MainActivity.getInstance().pushFragment(ProSellerDashboardFragment.newInstance(false), ProSellerDashboardFragment.class.getSimpleName(), true);
break;
case R.id.btnVerifyAndProceed:
if (validateOTP()) {
btnVerifyAndProceed.setEnabled(false);
HashMap<String, String> map = new HashMap<String, String>();
map.put("user_id", SharedPref.getUserId());
map.put("code", editTextForOTP.getText().toString());
verifyOTP(map, strFragment);
}
break;
default:
break;
}
}
protected void displayMessageAlert(String message, String title, final String error_code) {
String s = "Alert";
if (title != null && title.length() > 0) {
s = title;
}
if (message != null) {
new AlertDialog.Builder(ctx).setTitle(s).setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (error_code.toLowerCase().equals("logout")) {
AppUtil.logoutUser((MainActivity) ctx);
MainActivity.getInstance().pushFragment(LoginFragment.newInstance(true, true), LoginFragment.class.getSimpleName(), true);
}
dialog.dismiss();
}
}).show();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (broadcastReceiver != null) {
ctx.unregisterReceiver(broadcastReceiver);
}
}
public void setPopFragmentListener(popFragmentListener mPopFragmentListener) {
this.mPopFragmentListener = mPopFragmentListener;
}
public interface popFragmentListener {
void gotoRootFragment();
}
}
show()
in fragment? – Revanchismshow
inside async-task? – Tremblay