我正在使用优秀的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)。由于没有引用我的任何代码,它是一个库错误吗?
答案 0 :(得分:10)
我不得不在项目中调试相同的问题。
通常使用Dialog片段如下所示
@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成员变量mDialog上的方法。
答案 1 :(得分:9)
这是我在StackOverflow中报告的相对常见的崩溃,并且由于对话框未正确创建,导致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
}
虽然上述情况可能比崩溃更好,但这并不能解决无法创建对话框的根本原因。可能有很多原因,需要调试的是什么。
在我的情况下,我发现我需要实现DialogFragment的onCreateDialog()而不是 onCreateView(),以便在100%的时间内正确创建对话框。 (onCreateView()几乎总是可以创建对话框,但我保证有可重现的极端情况,其中onCreateView()无法工作,导致mDialog变为null。另一方面,我总是发现onCreateDialog()正确创建了DialogFragment& #39; s对话框。)
答案 2 :(得分:1)
我有NPE。
但用super.OnActivityCreated
围绕try/catch
并没有帮助。
有助于删除复制示例遗留下来的静态字段。 因此,重写的DialogFragment中没有静态字段。
答案 3 :(得分:1)
DialogFragment.mDialog
之前调用DialogFragment.dismiss()
,则 onActivityCreated()
可以为null。
答案 4 :(得分:0)
不,不是。如果SetContentView崩溃,这是常见错误。 setContentView调用视图控件的构造函数。一个抛出了nullPointerException。
答案 5 :(得分:0)
如果要覆盖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();