Ошибка DialogFragment.dismiss с использованием NullPointerException - программирование
Подтвердить что ты не робот

Ошибка DialogFragment.dismiss с использованием NullPointerException

Я делаю некоторые фоновые работы и показывая DialogFragment, пока я это делаю. Как только моя работа будет выполнена, и соответствующий ответ будет вызван, я отклоню диалог. Когда я это делаю, я получаю сбой, вызванный NPE в источнике Android, здесь:

void dismissInternal(boolean allowStateLoss) {
        if (mDialog != null) {
            mDialog.dismiss();
            mDialog = null;
        }
        mRemoved = true;
        if (mBackStackId >= 0) {
            getFragmentManager().popBackStack(mBackStackId,
                    FragmentManager.POP_BACK_STACK_INCLUSIVE);
            mBackStackId = -1;
        } else {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.remove(this);
            if (allowStateLoss) {
                ft.commitAllowingStateLoss();
            } else {
                ft.commit();
            }
        }
    }

в частности: FragmentTransaction ft = getFragmentManager().beginTransaction();

4b9b3361

Ответ 1

Это может также произойти, когда вы вызываете функцию увольнения(), прежде чем вы вызываете show(), как сказал Соггер.

После создания объекта Dialog, но до того, как диалог не будет показан, можно (mDialog!= null) передать событие NullPointerException.

Когда вы проверяете, является ли mDialog нулевым или нет,

if (mDialog != null) {
    mDialog.dismiss();
    mDialog = null;
}

Добавьте дополнительные условия, как показано ниже,

if ((mDialog != null) && mDialog.isAdded() && mDialog.isResumed()) {
    mDialog.dismiss();
    mDialog = null;
}

Я думаю, что условие mDialog.isAdded() может быть достаточно...

Ответ 2

Самое простое решение - проверить "getFragmentManager()" на "null" перед вызовом метода "Отклонить()". Также вы можете расширить класс "DialogFragment" и переопределить метод "Отклонить()", чтобы проверить его там:

@Override
public void dismiss()
{
    if (getFragmentManager() != null) super.dismiss();
}

Ответ 3

Я знаю, что это сообщение устарело, но я столкнулся с аналогичным случаем, который мне нужно решить без рефакторинга или изменения большого количества кода. Надеюсь, это полезно для кого-то.

   package com.example.playback;

import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class SaferDialogFragment extends DialogFragment {

    private boolean allowStateLoss = false;
    private boolean shouldDismiss = false;

    public SaferDialogFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public void onStart() {
        super.onStart();
        //check if we should dismiss the dialog after rotation
        if (shouldDismiss) {
            if (allowStateLoss)
                dismissAllowingStateLoss();
            else
                dismiss();
        }
    }

    @Override
    public void dismiss() {
        if (getActivity() != null) { // it "safer" to dismiss
            shouldDismiss = false;
            super.dismiss();
        } else {
            shouldDismiss = true;
            allowStateLoss = false;
        }
    }

    @Override
    public void dismissAllowingStateLoss() {
        if (getActivity() != null) { // it "safer" to dismiss
            shouldDismiss = false;
            super.dismissAllowingStateLoss();
        } else
            allowStateLoss = shouldDismiss = true;
    }

    //keeping dialog after rotation
    @Override
    public void onDestroyView() {
        if (getDialog() != null && getRetainInstance())
            getDialog().setDismissMessage(null);
        super.onDestroyView();
    }



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        /** omitted code **/
        return super.onCreateView(inflater, container, savedInstanceState);
    }
}

Ответ 4

Моя ставка будет заключаться в том, что код, который вы отправили, из фонового потока... вам не разрешено обновлять пользовательский интерфейс из любого другого места, кроме потока пользовательского интерфейса.

Вы можете использовать onPostExecute() или runOnUiThread() для достижения своей цели (если моя догадка правильна о том, что происходит)

Ответ 5

Проверка наличия видимости перед сглаживанием может исключить это исключение нулевого указателя

    if (mDialog != null && mDialog.isVisible) {
        mDialog.dismiss();
        mDialog = null;
    }

Ответ 6

Обратный вызов, который вызывается, вероятно, относится к активности, которая или должна быть уничтожена (после изменения ориентации), также может быть создан диалог выполнения с тем же самым действием. Это может вызвать NPE. Обратные вызовы по действиям не должны вызываться из фоновых задач, чтобы предотвратить эти проблемы. Отмените фоновую задачу из действия, например, используя otto, или не позволяйте фоновой задаче вызывать действие (быть) уничтоженным.

Это мой код:

статический внутренний класс деятельности:

    public static class ProgressDialogFragment extends DialogFragment {
    ProgressDialog dialog;

    public ProgressDialogFragment() {
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        dialog = new ProgressDialog(getActivity(), getTheme());
        dialog.setTitle(getString(R.string.please_wait));
        dialog.setMessage(getString(R.string.uploading_picture));
        dialog.setIndeterminate(true);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        return dialog;
    }

}

Отто подписка в действии:

@Subscribe
public void onUploadEvent(UploadAvatarEvent uploadAvatarEvent) {
    switch (uploadAvatarEvent.state) {
        case UploadAvatarEvent.STATE_UPLOADING:
            if (!mProgressDialog.isAdded()) {
                mProgressDialog.show(getFragmentManager(), TAG_PROGRESS_DIALOG);
            }
            break;
        case UploadAvatarEvent.STATE_UPLOAD_SUCCES:
            mProgressDialog.dismiss();
            break;
        case UploadAvatarEvent.STATE_UPLOAD_ERROR:
            mProgressDialog.dismiss();
            break;
    }
}

onCreate() в действии:

        mProgressDialog = (ProgressDialogFragment) getFragmentManager().findFragmentByTag(TAG_PROGRESS_DIALOG);
    if (mProgressDialog == null) {
        mProgressDialog = new ProgressDialogFragment();
    }