【问题标题】:getActivity() NullPointerException After Entering Multi-Window Mode进入多窗口模式后getActivity() NullPointerException
【发布时间】:2018-01-20 15:01:01
【问题描述】:

我有一个片段,当按下按钮时会弹出一个 PopupWindow。 在这个 PopupWindow 中,有一个 TextView 和另一个 Button。 按下此按钮会将文本放入剪贴板的 TextView 中,并显示 Toast。

我所有的按钮 OnClickListeners 和视图初始化都是在 Fragment 的 OnCreateView 方法中完成的。

如果我调出 PopupWindow 然后进入多窗口模式(按住 Nougat+ 上的“概览”按钮),PopupWindow 仍将存在,而 TextView 保持不变。但是,如果我按下 PopupWindow 中的按钮,我会从 OnClickListener 中的 getActivity() 调用中获得 NullPointerException。

相关代码:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_balance_equation, container, false);

    // initialize PopupWindow assets
    popupView = inflater.inflate(R.layout.popupwindow_layout, null);
    copyButton = (Button) eqnView.findViewById(R.id.copy_button);

    myPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

    copyButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String equation = ((TextView) eqnView.findViewById(R.id.balanced_equation)).getText().toString();
            ClipData clip = ClipData.newPlainText("balanced equation", equation);
            clipboard.setPrimaryClip(clip);
            if (toast != null){
                toast.cancel();
            }
            // **Null Pointer Exception here**
            toast = Toast.makeText(getActivity(), "Equation Copied", Toast.LENGTH_SHORT);
            toast.show();
        }
    });
    return rootView;
}

堆栈跟踪:

FATAL EXCEPTION: main
                                               Process: com.example.riesz.chemicalequationbalancer, PID: 14126
                                               java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                   at android.widget.Toast.<init>(Toast.java:102)
                                                   at android.widget.Toast.makeText(Toast.java:260)
                                                   at com.example.riesz.chemicalequationbalancer.BalanceEquationFragment$2.onClick(BalanceEquationFragment.java:200)
                                                   at android.view.View.performClick(View.java:5612)
                                                   at android.view.View$PerformClick.run(View.java:22285)
                                                   at android.os.Handler.handleCallback(Handler.java:751)
                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                   at android.os.Looper.loop(Looper.java:154)
                                                   at android.app.ActivityThread.main(ActivityThread.java:6123)
                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

编辑:

Nivesh 提供了一个解决方案,但我不完全理解它的工作原理。您可以通过覆盖 onAttach() 来获取 Activity 的实例并将其全局存储以供以后使用,这是非常有意义的。但是为什么对 getActivity() 的调用没有完成同样的事情,特别是因为我以相同的方式多次使用 getActivity() 并且这些调用都没有引发异常?

要明白我的意思,这是我的整个 java 文件:https://pastebin.com/Z5cWrVZ4

(我已经在这里实现了 Nivesh 的解决方案,所以这不会引发异常。在 copyButton OnClickListener 中将 Toast makeText() 的上下文参数更改回 getActivity() 会引发异常,就像在我的以前的代码sn-p。)

请注意,我在其他 OnClickListeners 中对 Toast 的使用与所有内容完全相同,但只有 copyButton 失败。

编辑 2:

我检查了 getActivity() 是否在 OnCreateView() 和 copyButton 侦听器中返回 null:在这两种情况下它都不是 null。那为什么还会有 NullPointerException 呢?

【问题讨论】:

    标签: android nullpointerexception fragment android-popupwindow


    【解决方案1】:

    为活动创建全局对象,如下所示:

    private Activity activity;
    
    @overide
    OnAttach(Activity activity)
    {
      this.activity = activity;
    }
    

    在片段类中的任何位置使用活动对象。

    【讨论】:

    • 嗯,这行得通。你能解释一下这里的推理吗?我的理解是在 onCreateView() 之前调用 onAttach() 并允许我获取 Activity 的实例。但这引出了一个问题:getActivity() 试图做什么......为什么它不能完成同样的事情?而且,我已经使用 getActivity() 在许多其他地方以完全相同的方式(在其他 OnClickListeners 中)提供 Toast 上下文,并且在激活多窗口模式之前和之后它们都可以正常工作。这是怎么回事?
    • 这是一个简单的事情,当你写 getActivity() 意味着调用片段的方法谁给你活动实例或 onAttach() 方法直接给你活动实例而不调用任何方法。使用 getActivity() 获取活动实例是一项繁重的任务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多