DialogFragment: NullPointerException (библиотека поддержки)

Я использую отличную библиотеку ACRA для получения отчетов об ошибках из своих приложений.

Я получаю много отчетов от клиентов о NPE в DialogFragment, но Im не смог воспроизвести его:

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). Поскольку нет ссылки на какой-либо из моего кода, это ошибка библиотеки?

Ответы

Ответ 1

Это довольно распространенный сбой, который я видел в StackOverflow, и из-за неправильного создания диалога, в результате чего mDialog будет null. Метод грубой силы, который я первоначально использовал для предотвращения сбоя:

@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 становится нулевым. С другой стороны, я всегда обнаружил, что onCreateDialog() правильно создал DialogFragment диалоговое окно.)

Ответ 2

Мне пришлось отлаживать ту же проблему в проекте.

Обычно фрагмент диалога используется как ниже

@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.

Ответ 3

У меня был NPE.

Но окружение super.OnActivityCreated с помощью try/catch не помогло.

Что помогло устранить статическое поле, которое осталось от копирования примера. Итак, никаких статических полей внутри переопределенного диалогового окна.

Ответ 4

Нет, нет. Это общая ошибка, если сработает SetContentView. setContentView вызывает конструкторы элементов управления вашего представления. Один из них выбрал исключение nullPointerException.

Ответ 5

Если вы переопределяете onCreateView (..) для создания экземпляра вашего диалогового окна, вам нужно показать его с помощью транзакции фрагмента и поместить 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();