Quantum Dot
Quantum Dot

Reputation: 395

getActivity() NullPointerException After Entering Multi-Window Mode

I have a Fragment that brings up a PopupWindow when a Button is pressed. In this PopupWindow, there is a TextView and another Button. Pressing this Button puts the text in the TextView in the Clipboard and also shows a Toast.

All of my button OnClickListeners and view initializations are done in the Fragment's OnCreateView method.

If I bring up the PopupWindow and then go into multi-window mode (holding the "Overview" button on Nougat+), the PopupWindow will still be present with the TextView unchanged. But then, if I press the Button in the PopupWindow, I get a NullPointerException from my getActivity() call within the OnClickListener.

Relevant code:

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;
}

Stack trace:

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)

EDIT:

Nivesh provided a solution but I don't fully understand why it works. It makes perfect sense that you can get an instance of the Activity by overriding onAttach() and store this globally for use later on. But why does the call to getActivity() not accomplish the same thing, especially since I used getActivity() multiple times in the same way and none of those calls raised an exception?

To see what I mean, here is my entire java file: https://pastebin.com/Z5cWrVZ4.

(I have implemented Nivesh's solution already here so this doesn't throw the exception. Changing the context parameter of Toast makeText() back to getActivity() in the copyButton OnClickListener throws the exception, as it did in my previous code snippet.)

Notice how my usage of Toasts in other OnClickListeners is exactly the same everything, yet only fails with the copyButton.

EDIT 2:

I have checked if getActivity() returns null in OnCreateView() and inside the copyButton listener: it is non-null in both cases. So then why is there even a NullPointerException?

Upvotes: 0

Views: 587

Answers (1)

nivesh shastri
nivesh shastri

Reputation: 440

Make global object for activity like below:

private Activity activity;

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

Use activity object anywhere in your fragment class.

Upvotes: 2

Related Questions