Butterknife 片段旋转给出 NullPointer

Posted

技术标签:

【中文标题】Butterknife 片段旋转给出 NullPointer【英文标题】:Butterknife fragment rotation giving NullPointer 【发布时间】:2015-01-16 02:33:48 【问题描述】:

我在我的应用程序中使用 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"));

以及活动中的调用:

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) 你的代码在你的活动中如何恢复片段实例或重新创建一个新实例也会有帮助 刚刚根据您指出的观察结果进行了编辑! 首先:我猜自方向更改以来数据没有改变,因此没有必要重新加载所有内容。您有其他方向的替代布局吗?如果是,请检查是否有 ID 为“userSearchName”的 TextView。还要在行上设置一个断点,并在您的调试器中查看精确的 null 是什么,也许 .get("firstName") 或 .get("lastName") 返回 null 是的,我将有另一种景观布局!但你是对的,数据不会改变,我会缓存它!但是 textview 是空的,而不是列表!我调试并仔细检查了它!谢谢 你能发布你的横向布局文件吗? 【参考方案1】:

在方向改变时,应用程序将调用 onDestroy()。在您的情况下,这将通过调用“ButterKnife.reset”来重置 ButterKnife 注入。

但在方向更改生命周期中不会调用 onCreateView。

如果将 ButterKnife 注入调用从 onCreateView 移至 onViewCreated,问题可能会得到解决。

【讨论】:

【参考方案2】:

实际上,我通过使用来自https://github.com/greenrobot/EventBus 的 EventBus 解决了这个问题。 我只是在回调上使用一个 post 事件并在片段本身上获取它,然后我管理视图更改。

像这样:

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

谢谢!

【讨论】:

以上是关于Butterknife 片段旋转给出 NullPointer的主要内容,如果未能解决你的问题,请参考以下文章

将 Butterknife 与 BaseActivity/Child 活动和 MaterialDrawer 一起使用

Butterknife 在我的 Android 应用程序中根本不起作用

ButterKnife 8.6.0无法正常工作

使用 ActionBar 旋转 Android 的双片段

如何在没有活动旋转的情况下旋转活动内的片段?

旋转后片段字段为空