我的应用程序崩溃了。基本上,我有一个片段,其中必须在一个场景中显示对话框。我通过扩展对话框片段创建了对话框。问题是某些用户崩溃抛出空指针异常。 这是对话框的片段:
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());
该应用程序在第二行崩溃。从崩溃论者中,我得到了以下堆栈跟踪:
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)
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)
据我所知,片段管理器在某些时候变为空。但是,我无法重现该场景。崩溃发生在没有。几乎每天都有用户。
更新:(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 :(得分:4)
你应该在之前获得片段管理器:
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库来支持片段
答案 1 :(得分:1)
如果您从片段中显示,请使用getChildFragmentManager()
:
喜欢:
verifyOTPDialog.show(getChildFragmentManager(),VerifyOTPDialog.class.getSimpleName());
答案 2 :(得分:1)
您说您使用android.app.fragment
来托管您的片段。由于您使用android DialogFragment进行对话,因此对话框Fragment本身就是一个片段,因此这就是android中嵌套Fragments的情况。当我们嵌套frgaments时,我们使用getChildFragmentManager().
在API 11中没有支持android中的嵌套片段。嵌套片段的支持从API 17开始,然后从API开始。如果要在API 11-16中使用嵌套片段,则必须使用支持库片段。
所以你必须制作类型为android.support.v4.app.dialogFragment
的DialogFragment和类型为android.support.v4.app.fragment
答案 3 :(得分:0)
我建议从父活动调用 DialogFragment ,这样就不会遇到片段生命周期的问题。由于您可能试图让片段相互通信,因此应该通过Activity完成。
以下是更多信息 - https://developer.android.com/training/basics/fragments/communicating.html
遵循以下步骤:
最后一步是你可以调用DialogFragment,然后让Dialog将数据返回给活动,然后将其传递给调用的Fragment。