接口/捆绑包的空对象引用

时间:2019-06-27 09:24:31

标签: android interface

我有一个收集付款信息的屏幕。在这里,用户可以按“后退”按钮在ShopFragment中更改其采购订单,也可以按“提交”按钮转到ConfirmationFragment。 “后退”按钮可以正常工作,但“提交”按钮会导致此错误:

06-27 01:07:38.321 14771-14771/com.shop.away E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.shop.away, PID: 14771
    java.lang.NullPointerException: Attempt to invoke interface method 'void com.shop.away.ui.PaymentFragment$OnPaymentSubmitListener.onPaymentSubmit(android.os.Bundle)' on a null object reference
        at com.shop.away.ui.PaymentFragment$7.onSuccess(PaymentFragment.java:294)
        at com.shop.away.ui.PaymentFragment$7.onSuccess(PaymentFragment.java:289)
        at com.google.android.gms.tasks.zzn.run(Unknown Source)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:158)
        at android.app.ActivityThread.main(ActivityThread.java:7224)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是 PaymentFragment 的代码:

private OnPaymentSubmitListener paymentSubmitListener;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        paymentView = inflater.inflate(R.layout.fragment_payment, container, false);

btnBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                bundle.putBoolean("direction", false);
                paymentSubmitListener.onPaymentSubmit(bundle);
            }
        });

        btnPlaceOrder.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                getToken();
            }
        });
        return paymentView;
    }

private void getToken() {
// If token obtained successfully place order
}

private void placeOrder() {
if (orderPlaced.isSuccessful) {
bundle.putBoolean("direction", true);
                paymentSubmitListener.onPaymentSubmit(bundle);
}

public void onButtonPressed(Bundle bundle) {
        if (paymentSubmitListener != null) {
            paymentSubmitListener.onPaymentSubmit(bundle);
        }
    }

    @Override
    public void onAttach(Context context) {
        paymentContext = context;
        super.onAttach(paymentContext);
        if (context instanceof OnPaymentSubmitListener) {
            paymentSubmitListener = (OnPaymentSubmitListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        paymentSubmitListener = null;
    }

    public interface OnPaymentSubmitListener {
        void onPaymentSubmit(Bundle bundle);
    }
}

在我的 MainActivity 中,这就是我处理界面的方式:

public void onPaymentSubmit(Bundle bundle) {
        if (bundle != null && bundle.containsKey("direction")) {
            Boolean direction = bundle.getBoolean("direction");
            if (!direction) {
                ShopFragment fragment = new ShopFragment();
                openFragment(bundle, fragment, direction);
            } else {
                ConfirmationFragment fragment = new ConfirmationFragment();
                openFragment(bundle, fragment, direction);
            }
        }
    }

private void openFragment(Bundle bundle, Fragment fragment, Boolean direction) {
// Open corresponding fragment using animation
}

PaymentFragment.java:294 在此专门引用此行:paymentSubmitListener.onPaymentSubmit(bundle)

1 个答案:

答案 0 :(得分:0)

onCreateView()中初始化您的侦听器并添加检查

if(paymentSubmitListener != null)

使用之前。

之所以得到空指针,是因为未初始化返回到先前的片段侦听器,因为仅在附加了片段且恢复到片段时才调用onAttach(Context context),但监听器字段初始化已消失。 >

尝试移动此部分

  if (context instanceof OnPaymentSubmitListener) {
            paymentSubmitListener = (OnPaymentSubmitListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
}

进入public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

通过这种方式,我建议您重新考虑您的体系结构,因为我认为将上下文用作侦听器实例不是一种好习惯。更好的主意是使Fragment实现侦听器并将其用作this

另一种想法是,片段中的Context可能是null