旋转设备后的空指针异常(Sherlock DialogFragment)

时间:2013-10-26 14:54:17

标签: android nullpointerexception actionbarsherlock

我有:

public class LocationSelectionFragment extends SherlockDialogFragment implements
        LocationImageChangeListener, DeleteActionListener {
// some code...
// ...
    public void onLocationImageRemove(int position) {
        Log.message("Enter");
        Log.variable("position", String.valueOf(position));
        mPosition = position;
        ConfirmDeleteFragment deleteFragment = ConfirmDeleteFragment.NewInstance(mAdapter.getItem(position).locationName, this);
        deleteFragment.show(getFragmentManager(), Constants.DELETE_DIALOG);
    }

    private void deleteRecord() {
        LocationRecord record = mAdapter.getItem(mPosition);

        mDbAdapter.deleteLocation(record._id);
        mAdapter.remove(record);
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onDeleteLocation() {
        Log.message("Enter");
        dismiss();
            //deleteRecord();

    }

我的ConfirmDeleteFragment类:

/**
 * Implements delete confirmation dialog
 */
public class ConfirmDeleteFragment extends SherlockDialogFragment {
    /**
     * Interface for delete action
     */
    public interface DeleteActionListener{
        /**
         * Listener for handling delete location
         */
        public void onDeleteLocation();
    }

    private static DeleteActionListener mCallback;
    private String mLocationName;

    static public ConfirmDeleteFragment NewInstance(String locationName, DeleteActionListener callback) {
        ConfirmDeleteFragment deleteDialog = new ConfirmDeleteFragment();
        deleteDialog.mLocationName = locationName;
        ConfirmDeleteFragment.mCallback = callback;
        return deleteDialog;
    }

    public ConfirmDeleteFragment() {
        super();
    }


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Log.message("Enter");

        if (savedInstanceState != null) {
            mLocationName = savedInstanceState.getString(Constants.DELETE_LOCATION_NAME);
        }

        String message = String.format(Locale.US, getString(R.string.sunset_deleteConfirm_message), mLocationName);
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());

        // Setting Dialog Title
        alertDialog.setTitle(R.string.sunset_deleteConfirm_title);

        // Setting Dialog Message
        alertDialog.setMessage(message);

        // On pressing Delete button
        alertDialog.setPositiveButton(R.string.sunset_deleteConfirm_positive,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        mCallback.onDeleteLocation();
                    }
                });

        // on pressing cancel button
        alertDialog.setNegativeButton(R.string.sunset_deleteConfirm_negative,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        return alertDialog.create();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putString(Constants.DELETE_LOCATION_NAME, mLocationName);
    }
}

空指针异常的步骤:

  1. 用户打开对话框LocationSelectionFragment。
  2. 用户点击删除图片并打开ConfirmDeleteFragment。
  3. 用户旋转设备并确认操作。结果 - NullPointer异常:

    10-26 10:42:48.747: E/AndroidRuntime(3657): java.lang.NullPointerException
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:184)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at android.support.v4.app.DialogFragment.dismiss(DialogFragment.java:155)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at ru.neverdark.phototools.fragments.LocationSelectionFragment.onDeleteLocation(LocationSelectionFragment.java:231)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at ru.neverdark.phototools.fragments.ConfirmDeleteFragment$1.onClick(ConfirmDeleteFragment.java:83)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:166)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at android.os.Handler.dispatchMessage(Handler.java:99)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at android.os.Looper.loop(Looper.java:137)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at android.app.ActivityThread.main(ActivityThread.java:5103)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at java.lang.reflect.Method.invokeNative(Native Method)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at java.lang.reflect.Method.invoke(Method.java:525)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    10-26 10:42:48.747: E/AndroidRuntime(3657):     at dalvik.system.NativeStart.main(Native Method)
    
  4. 如果没有旋转装置 - 工作正常。 在日志中,我可以看到方法onResume在两种情况下都调用了LocationSelectionFragment(有旋转和没有旋转)但是在旋转的情况下 - 当我为LocationSelectionFragment调用dismiss时粉碎。为什么?

1 个答案:

答案 0 :(得分:0)

我修复了NullPointer异常问题:

重写LocationSelectionFragment类的方法:

public void onLocationImageRemove(int position) {
    Log.message("Enter");
    Log.variable("position", String.valueOf(position));

    ConfirmDeleteFragment deleteFragment = ConfirmDeleteFragment.NewInstance(mAdapter.getItem(position).locationName, position);
    deleteFragment.setTargetFragment(this, Constants.DELETE_DIALOG_FRAGMENT);
    deleteFragment.show(getFragmentManager(), Constants.DELETE_DIALOG);
}


public void onDeleteLocation(final int position) {
    Log.message("Enter");

    Log.variable("Position", String.valueOf(position));

    dismiss();

}

重写类ConfirmDeleteFragment:

public class ConfirmDeleteFragment extends SherlockDialogFragment {


    private String mLocationName;
    private int mPosition;

    static public ConfirmDeleteFragment NewInstance(String locationName, int position) {
        ConfirmDeleteFragment deleteDialog = new ConfirmDeleteFragment();
        deleteDialog.mLocationName = locationName;
        deleteDialog.mPosition = position;
        return deleteDialog;
    }

    public ConfirmDeleteFragment() {
        super();
    }


    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Log.message("Enter");

        if (savedInstanceState != null) {
            mLocationName = savedInstanceState.getString(Constants.DELETE_LOCATION_NAME);
            mPosition = savedInstanceState.getInt(Constants.DELETE_LOCATION_POSITION);
        }

        String message = String.format(Locale.US, getString(R.string.sunset_deleteConfirm_message), mLocationName);
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());

        // Setting Dialog Title
        alertDialog.setTitle(R.string.sunset_deleteConfirm_title);

        // Setting Dialog Message
        alertDialog.setMessage(message);

        // On pressing Delete button
        alertDialog.setPositiveButton(R.string.sunset_deleteConfirm_positive,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
((                        LocationSelectionFragment) getTargetFragment()).onDeleteLocation(mPosition);
                    }
                });

        // on pressing cancel button
        alertDialog.setNegativeButton(R.string.sunset_deleteConfirm_negative,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        // Showing Alert Message
        return alertDialog.create();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putString(Constants.DELETE_LOCATION_NAME, mLocationName);
        outState.putInt(Constants.DELETE_LOCATION_POSITION, mPosition);
    }

它解决了我的问题。