Butterknife在片段旋转时出现空指针异常

4
我将使用ButterKnife 6.0.0在我的应用程序中,但是在旋转片段后,我会收到NullPointerException:
我的代码:
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);
                    }
                });
            }
        });
    }

堆栈跟踪:
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)

----编辑----

第 101 行

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

在活动中的调用:


注:本文为IT技术相关内容。
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();
    }

任何帮助都将不胜感激!

你能指出你的代码中第101行是哪一行吗?(AddFriendFragment.java:101)另外,你在Activity中如何恢复Fragment实例或创建一个新实例会很有帮助。 - Angelo
刚刚根据你指出的观察进行了编辑! - Leonardo
首先:我猜数据在屏幕方向改变后没有改变,所以不需要重新加载所有内容。你在另一个屏幕方向中有替代布局吗?如果有,请检查是否有一个ID为'userSearchName'的TextView。同时,在该行设置断点并在调试器中查看确切的空值,也许是.get("firstName")或.get("lastName")返回了空值。 - Angelo
好的,我会为横向布局提供另一个布局!但你说得对,数据不会改变,我会将其缓存!但是TextView为空,而不是列表!我已经进行了调试并仔细检查了它!谢谢。 - Leonardo
你能发布你的横向布局文件吗? - iagreen
我还没有开发它,只有肖像版本。 - Leonardo
2个回答

2

在屏幕方向变化时,应用程序会调用onDestroy()方法。在您的情况下,这将通过调用'ButterKnife.reset'来重置ButterKnife注入。

但是,在屏幕方向变化生命周期中不会调用onCreateView方法。

如果您将ButterKnife注入调用从onCreateView移动到onViewCreated,则可能会解决此问题。


1
实际上,我通过使用https://github.com/greenrobot/EventBus中的EventBus解决了这个问题。我只需在回调函数中发布一个事件,然后在片段本身获取它,然后管理视图更改。
就像这样:
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));
            }
        });   

然后:

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

感谢!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接