Android: fragment 管理器变为空

标签 android android-fragments android-dialogfragment fragmentmanager

我的应用程序崩溃了。基本上,我有一个 fragment ,其中必须在一个场景中显示一个对话框。我通过扩展对话框 fragment 创建了对话框。问题是对于某些用户来说,它会崩溃并抛出空指针异常。 这是对话框的 fragment :

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

应用程序在第 2 行崩溃。从 crashlytics,我得到了以下堆栈跟踪:

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。崩溃:主要: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)

据我所知, fragment 管理器在某个时间点变为空。但是,我无法重现该场景。没有发生崩溃。几乎每天都有用户。

更新:(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();
}
}

最佳答案

你应该在之前获得 fragment 管理器:

FragmentManager fragMan = getSupportFragmentManager();

然后测试它是否无效

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

如果你在 asynctask 的 DoInBackground 中使用 if 你应该得到 Uithread :

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

编辑:

您应该使用 support v4 库来支持 fragment

关于Android: fragment 管理器变为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38568709/

相关文章:

android - 如何使用共享首选项重置所有存储的数据存储

android - SwipeRefreshLayout 刷新与 fragmentTransactions 冲突

Android - 对话框 fragment 顶部的 float 操作按钮

android - Android 上 ListView 中的 MediaPlayer

android - 使用 Espresso 和 RxJava 测试无限滚动 RecyclerView

android - 在 Fragment 中实现 DatePicker

java - 为什么 DialogFragment.dismiss 不立即终止对话框?

java - 区分配置更改和真正关闭,在 DialogFragment 的 onDimiss 回调中

android - 用安卓相机捕捉 ISBN 号

android - 方向更改时 fragment View 为空