java.util.Objects.requireNonNull上的java.lang.NullPointerException

时间:2019-01-15 08:47:56

标签: java android android-fragments

在我的代码中,我正在从一个活动中调用以下函数addFood

postFood f = new postFood();
f.addFood(context, breakfastDate, breakfastSearch, 1);

然后代码运行以下代码

public class postFood extends DialogFragment {
    @SuppressLint("StaticFieldLeak")
    private static Context context1;
    @SuppressLint("StaticFieldLeak")
    private static ListView dateList1, selectedList1;
    private static ProgressDialog progressDialog;
    private static int mealType1;
    private static String TAG = "AddSelectedFood";
    private static String date;
    private static String time;
    public static String[] dateTimeString;
    public static Calendar cal;


    public  void addFood(Context context, ListView dateList, ListView selectedList,
                           int mealType) {
        dateList1 = dateList;
        selectedList1 = selectedList;
        context1 = context;
        mealType1 = mealType;
        //*FragmentManager manager = Objects.requireNonNull(this.getActivity()).getSupportFragmentManager();

        // Use the current date as the default date in the picker
        new datePickerFragment().show(Objects.requireNonNull(getActivity()).getSupportFragmentManager(), "datePicker");
    }
}

为了防止getActivity()。getSuppotFragmentManaget为空,我该怎么办?

这是我的日志

2019-01-15 12:08:37.898 7908-7908/com.example.khali.nutriplan E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.khali.nutriplan, PID: 7908
java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at com.example.khali.nutriplan.postFood.addFood(postFood.java:63)
    at com.example.khali.nutriplan.breakfastPage$1.onClick(breakfastPage.java:114)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25885)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

3 个答案:

答案 0 :(得分:0)

很难说出getActivity()为null的原因,因为我们不知道您在哪里调用您的方法。

您必须知道getActivity()之前onAttach()之前和onDestroy()之后为null,如果您在这两个方法之间调用您的方法,那应该很好。

我该怎么做才能防止getActivity()。getSuppotFragmentManaget为空?

大胆地回答您的问题。当您在代码中使用getActivity()时,最好将其强制转换以确保它不为null(除非您确定它不为null)。在您的代码中,就是这样。

    // Use the current date as the default date in the picker
    if (getActivity != null){
        new datePickerFragment().show(Objects.requireNonNull(
            getActivity()).getSupportFragmentManager(), "datePicker");
    }

使用这些,您将不会遇到getActivity.getSupportFragmentManager()为空的问题。 BUTT ,这是因为您的代码的这一部分将不再运行。它将看到getActivity()为空,并且不会遵循该代码。

从现在开始,您的应用程序将不再崩溃,但是,您将不会看到对话框。现在,您需要防止getActivity()为空。为此,我建议您这样做。

  1. 检查您要在哪里调用您的方法;
  2. 尝试从不同地方调用您的方法;
  3. 使用onAttach()时,请确保您的活动/片段处于onDestroy()getActivity()方法内。

答案 1 :(得分:0)

好,让我很快地解释一下。 vaibhav kumar在他的评论中提到的是正确的,但我认为您尚未完全理解。这个想法是将上下文从调用方Activity传递到Fragment。为什么?将片段视为小型UI元素,您可以动态地在Activity内部使用它们。在这里,我们来谈谈第一件重要的事情:确保包含您的片段的活动不仅是活动,而且是FragmentActivity。 现在,您可以做两件事:

  1. getFragmentManager():返回用于与与此片段活动相关联的片段进行交互的FragmentManager。请注意,从将片段放入FragmentTransaction到提交并附加到其活动之间的这段时间内,在getActivity()之前,该值将为非null。 这不是您的选择,因为很明显,任何活动都尚未使用您的片段。
  2. 使用您传递给片段的上下文。它包含有关当前活动的Activity的信息。请记住,您的片段仍未附着。所以您要做的是:context.getActivity(). getSupportFragmentManager()

这应该可以解决您的问题。始终牢记不同的states of a Fragment以及它们如何影响其行为。例如,您的片段还没有附加。

答案 2 :(得分:0)

您正在实例化片段,但没有将其添加到UI。由于在调用addFood方法时该片段未附加到活动,因此getActivity()返回null。

postFood f = new postFood();
f.addFood(context, breakfastDate, breakfastSearch, 1);

实例化后,应调用show方法将片段实例添加到UI

postFood f = postFood.newInstance(context, breakfastDate, breakfastSearch, 1);
f.show(getSupportFragmentManager(), "MyTAG");

并从片段中调用onViewCreated方法内的addFood方法

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState){
    super.onViewCreated(view, savedInstanceState);
    addFood(); }