Butterknife fragment rotation giving NullPointer

2.3k views Asked by At

I'm using ButterKnife 6.0.0 in my app, but after rotating a fragment I'm getting a NullPointerException:

My code:

public class AddFriendFragment extends Fragment {

    @InjectView(R.id.userSearchAddFriend)
    ImageButton addFriendBtn;
    @InjectView(R.id.userSearchName)
    TextView name;
    @InjectView(R.id.userSearchEmail)
    TextView email;
    @InjectView(R.id.userSearchProfilePicture)
    ImageView profile;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_userfragment, container,
                false);

        ButterKnife.inject(this, v);

        return v;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.reset(this);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


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

        final String id = getArguments().getString("user");

        ParseQuery<ParseUser> query = ParseUser.getQuery();
        query.fromLocalDatastore();
        query.whereEqualTo("objectId",id);
        query.getFirstInBackground(new GetCallback<ParseUser>() {
            @Override
            public void done(final ParseUser parseUser, ParseException e) {
                if(e != null || parseUser == null)
                {
                    //logar erro
                    return;
                }

                name.setText(parseUser.get("firstName") + " " + parseUser.get("lastName"));
                email.setText(parseUser.getUsername());
                ParseFile file =(ParseFile) parseUser.get("profileImg");
                if(file != null) {
                    Picasso.with(getActivity()).load(file.getUrl()).into(profile);
                }

                addFriendBtn.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        addFriend(parseUser);
                    }
                });
            }
        });
    }

The stack trace:

11-18 17:03:41.240    8468-8468/com.maddogs.mymoney E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.maddogs.mymoney, PID: 8468
    java.lang.NullPointerException
            at com.maddogs.mymoney.fragments.AddFriendFragment$1.done(AddFriendFragment.java:101)
            at com.maddogs.mymoney.fragments.AddFriendFragment$1.done(AddFriendFragment.java:92)
            at com.parse.GetCallback.internalDone(GetCallback.java:43)
            at com.parse.GetCallback.internalDone(GetCallback.java:29)
            at com.parse.Parse$6$1.run(Parse.java:940)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5086)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

---- Edit ----

The line 101

name.setText(parseUser.get("firstName") + " " + parseUser.get("lastName"));

And the call in the activity:

AddFriendFragment userFragm = new AddFriendFragment();
        Bundle bundle = new Bundle();
        bundle.putString("user",event.getUser().getObjectId());
        userFragm.setArguments(bundle);

        getSupportFragmentManager().beginTransaction()
                .replace(R.id.root_frame, userFragm)
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .addToBackStack(null).commit();
    }

Any help would be greatly appreciated!

2

There are 2 answers

0
Leonardo On BEST ANSWER

Actually I solved this by using the EventBus from https://github.com/greenrobot/EventBus. I simply use a post event on the callback and get it on the fragment itself, and then I manage the view change.

Like this:

query.fromLocalDatastore();
        query.whereEqualTo("objectId", id);
        query.getFirstInBackground(new GetCallback<ParseUser>() {
            @Override
            public void done(final ParseUser parseUser, ParseException e) {
                EventBus.getDefault().post(new AddFriendEvent(e == null, parseUser));
            }
        });   

And then:

  public void onEventMainThread(final AddFriendEvent event) {
            if (!event.isResult())
                return;

            name.setText(event.getUser().get("firstName") + " " + event.getUser().get("lastName"));
            email.setText(event.getUser().getUsername());
            ParseFile file = (ParseFile) event.getUser().get("profileImg");
            if (file != null) {
                Picasso.with(getActivity()).load(file.getUrl()).into(profile);
            }

            addFriendBtn.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    addFriend(event.getUser());
                }
            });

            addFriendBtn.setOnClickListener(null);
            addFriendBtn.setImageResource(R.drawable.ic_action_accept);
        }

Thanks !

0
SubinM On

On orientation change, the application will call onDestroy(). In your case this will reset the ButterKnife injection by calling 'ButterKnife.reset'.

But onCreateView is not called on orientation change lifecycle.

The issue may get solved if you move the ButterKnife injection call to onViewCreated from onCreateView.