6

Ich bekomme Abstürze für meine App. Grundsätzlich habe ich ein Fragment, in dem ein Dialog in einem Szenario angezeigt werden muss. Ich hatte den Dialog durch Erweiterung des Dialogfragments erstellt. Das Problem ist, dass es bei einigen Benutzern zu einem Absturz der Nullzeiger-Ausnahme kommt. Dies ist das Snippet-Dialog:Android: Fragment-Manager wird Null

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()); 

Die App stürzt in der 2. Zeile. Von crashlytics, bekam ich folgenden 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. Abgestürzt: 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) 

Soweit ich das Fragment Manager an einem gewissen Punkt der Zeit null wurde verstanden. Aber ich kann das Szenario nicht reproduzieren. Die Abstürze geschehen auf Nein. von Benutzern fast jeden Tag.

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(); 
} 
} 
+0

können Sie bitte hier Ihren VerifyOTPDialog setzen –

+0

Rufen Sie 'show()' im Fragment an? –

+0

Rufen Sie 'show' innerhalb async-task auf? – g4s8

Antwort

4

Sie das Fragment Manager, bevor bekommen sollte:

FragmentManager fragMan = getSupportFragmentManager();

dann testen Ungültigkeit

if(fragMan != null){ 
    // Do stuff 
} 

ist Und wenn Sie verwenden, wenn in DoInBackground des AsyncTask sollten Sie die Uithread erhalten:

runOnUiThread(new Runnable() { 
    public void run() { 
     // do stuff on the ui like display fragments 
    } 
}); 

EDIT:

Sie sollten die Unterstützung v4-Bibliothek verwenden für Fragment Unterstützung

0

Wenn Sie von Fragment zeigen, dann getChildFragmentManager() verwenden:

Like:

verifyOTPDialog.show(getChildFragmentManager(),VerifyOTPDialog.class.getSimpleName()); 
+0

Aber das ist von API 17 verfügbar. Auch ich benutze android.app.fragment – Nitish

+0

Dann müssen Sie 'android.support.v4.app.dialogFragment' für DialogFragment und für das Fragment verwenden Sie' android.support.v4.app .Fragment'. Sie müssen "FragmentActivity" oder "AppCompatActivity" in Ihrer Aktivität erweitern. Auf diese Weise können Sie 'getchildFragmentManager() 'in Fragment unter api 17 erhalten. –

1

Sie haben angegeben, dass Sie android.app.fragment verwenden, um Ihr Fragment zu hosten. Da Sie den Dialog mit dem DialogFragment von android erstellen, ist der Dialog Fragment selbst ein Fragment, was die Verschachtelung von Fragmenten in android bedeutet. Wenn wir Fragements verschachteln, verwenden wir getChildFragmentManager().

Die Unterstützung für verschachtelte Fragmente in Android war in API 11 nicht verfügbar. Die Unterstützung für verschachtelte Fragmente begann mit API 17 und höher. Wenn Sie verschachtelte Fragmente in API 11 - 16 verwenden möchten, müssen Sie die Fragmente der Support-Bibliothek verwenden.

So haben Sie Ihre DialogFragment vom Typ android.support.v4.app.dialogFragment und Ihr Fragment vom Typ machen android.support.v4.app.fragment

0

ich die DialogFragment von der übergeordneten Aktivität aufrufen würde empfehlen, so dass Sie nicht in Probleme mit dem Fragment Lebenszyklus laufen. Da Sie wahrscheinlich versuchen, die Fragmente miteinander kommunizieren zu lassen, sollte dies über die Aktivität erfolgen.

Hier weitere Informationen - https://developer.android.com/training/basics/fragments/communicating.html

die Schritte Folgende:

  1. Definieren Sie die Schnittstelle
  2. Implementieren Sie die Schnittstelle
  3. eine Nachricht an ein Fragment Deliver

Die letzte Schritt ist, wo Sie das DialogFragment aufrufen können und dann das Wählen haben Geben Sie die Daten zurück und übergeben Sie sie an das aufrufende Fragment.