DialogFragment:NullPointerException(支持库)

我使用优秀的ACRA库从我的应用程序接收错误报告。

我收到很多客户关于DialogFragment中的NPE的报告,但我无法复制它:

java.lang.NullPointerException at android.support.v4.app.DialogFragment.onActivityCreated(SourceFile:366) at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:892) at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1083) at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1065) at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(SourceFile:1844) at android.support.v4.app.FragmentActivity.onStart(SourceFile:519) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1133) at android.app.Activity.performStart(Activity.java:4475) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1929) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) at android.app.ActivityThread.access$600(ActivityThread.java:123) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4424) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) 

NPE发生在支持库 (@line 366)内:

 353 @Override 354 public void onActivityCreated(Bundle savedInstanceState) { (...) 361 View view = getView(); 362 if (view != null) { 363 if (view.getParent() != null) { 364 throw new IllegalStateException("DialogFragment can not be attached to a container view"); 365 } 366 mDialog.setContentView(view); 367 } 

我无法重现我的任何设备上的问题(从2.2到4.1.1)。 由于没有任何我的代码的参考,这是一个库错误?

Solutions Collecting From Web of "DialogFragment:NullPointerException(支持库)"

这是一个相对常见的崩溃,我已经看到在StackOverflow中报告,这是由于对话框没有正确创build,导致mDialog为空。 我最初用来防止崩溃的蛮力方法:

 @Override public void onActivityCreated(Bundle arg0) { if (getDialog() == null ) { // Returns mDialog // Tells DialogFragment to not use the fragment as a dialog, and so won't try to use mDialog setShowsDialog( false ); } super.onActivityCreated(arg0); // Will now complete and not crash 

}

虽然以上可能比崩溃更好,但这并不能解决导致对话失败的根本原因。 这可能有很多原因,这就是需要debugging的。

在我的情况下,我发现我需要实现DialogFragment的onCreateDialog() 而不是 onCreateView()来正确地创build对话框的100%的时间。 (onCreateView()几乎总是用来创build对话框,但是我确定有可重现的angular落案例,onCreateView()无法工作,导致mDialog变为null。另一方面,我总是发现onCreateDialog()正确创build了DialogFragment对话。)

我不得不在一个项目中debugging相同的问题。

通常使用对话框片段如下

 @Override public Dialog onCreateDialog (Bundle savedInstanceState) { //Create custom dialog return dialog; } 

尝试更新到以下

 @Override public Dialog onCreateDialog (Bundle savedInstanceState) { //Create custom dialog if (dialog == null) super.setShowsDialog (false); return dialog; } 

这将阻止DialogFragment.onAtivityCreated()从null成员variablesmDialog上执行方法。

我有NPE。

但是围绕super.OnActivityCreated使用try/catch没有帮助。

有帮助的是去除了复制实例时留下的静态字段。 所以,重写的DialogFragment中没有静态字段。

不,这不对。 如果SetContentView崩溃,这是常见的错误。 setContentView调用视图的控件的构造函数。 一个抛出一个nullPointerException。

如果您重写onCreateView(..)来实例化DialogFragment的视图,则需要使用片段事务来显示它,并将setShowsDialog设置为false以避免此错误。 即:

  //Instantiate your DialogFragment and fragmentManager previously and then just do this: dialogFragment.setShowsDialog(false); FragmentTransaction fT = fragmentManager.beginTransaction(); fT.add(0, dialogFragment, TAG); fT.commit();