Fragment 的 GetTag 返回空对象引用

Posted

技术标签:

【中文标题】Fragment 的 GetTag 返回空对象引用【英文标题】:GetTag of Fragment returns the null object reference 【发布时间】:2016-09-17 07:12:58 【问题描述】:

使用使用了多个片段的应用程序,并且 以下代码获取片段的选定位置。

private BaseFragment getSelectedFragment(FragmentManager fragmentManager)
    
        int item = getModel().getSelectedItem();//0th position last
        String tag = String.valueOf(item);
        BaseFragment fragment = (BaseFragment) fragmentManager.findFragmentByTag(tag); //error shown at this line
        return fragment;
    

并从

调用上述方法
public boolean onBackPressed() 

   FragmentManager fragmentManager = activity.getFragmentManager();
   BaseController fragmentController =             getSelectedFragment(fragmentManager).getController();

由于以下错误而崩溃

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'java.lang.String xxx.android.fwk.app.fragment.BaseFragment.getTag()'。

使用以下代码替换片段

private void displaySelectedFragment()
    

        FragmentManager fragmentManager = getFragmentManager();
        if (fragmentManager.getBackStackEntryCount() > 0) 
            // pop any inner fragments that have been added.
            fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        

        // get the selected item position
        int selectedItem = model.getSelectedDrawerItem().getItemId();

        String tag = String.valueOf(selectedItem);
        Bundle extras = model.getExtras();

        BaseFragment newFragment = NomadFragmentManager.getInstance().getFragment(selectedItem, extras);
        if (newFragment != null) 
            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            ft.replace(R.id.container, newFragment, tag);
            ft.commit();
        
    

那么真正的问题原因是什么?深入研究这段代码。 任何帮助都非常感谢。 提前致谢

【问题讨论】:

在替换片段时,您是否给片段添加了“标签”? @SurenderKumar :是的,在替换片段时证明标签,用片段替换代码更新答案。 你能在调用这个方法的地方添加代码吗?因为可能是片段管理器即将为空。 尝试检查您设置为片段的标签,同时使用日志查找片段时替换相同。试试这个。 @SurenderKumar : 在这一行将 Fragment 设为 null BaseFragment fragment = (BaseFragment) fragmentManager.findFragmentByTag(tag); 【参考方案1】:

引用Document

替换已添加到容器中的现有片段。这是 本质上与为所有当前调用 remove(Fragment) 相同 添加了使用相同 containerViewId 添加的片段,然后 add(int, Fragment, String) 与此处给出的参数相同。

替换 Fragment 会将其从后台堆栈中完全删除。因此,如果您在与其他Fragment 交易后尝试检索Tag,那么它将不可用。您应该使用将Fragments 添加到后台堆栈 addToBackStack(tagName).

【讨论】:

感谢您的建议。你提到的问题的深度。 在提交之前添加 addTobackstack(tag) 解决了问题【参考方案2】:

从您的崩溃日志来看,这似乎不是您遇到崩溃的行号。崩溃是由于从空片段调用 getTag() 造成的。也许在此方法返回 null 之后,然后您正在使用给出空指针异常的片段实例。

BaseFragment fragment = (BaseFragment) fragmentManager.findFragmentByTag(tag);
 if(fragment != null)
     return fragment.
 
 return null;

也许将调试点放在fragment != null 可能会澄清您的问题。

更新

在你的代码更新之后,你不应该再得到任何空指针。但你应该放一个日志来检查它是否变为空。

【讨论】:

bpr10 :我在行号显示的地方添加了一条注释,并会尝试进行调试,但这个问题的实际原因是什么? 我在这一行下面加了一条日志,BaseFragment fragment = (BaseFragment) fragmentManager.findFragmentByTag(tag);最后一个 fragment.getTag 显示第 0 个位置,应用程序严重崩溃!!!! 能否更新您问题中的完整代码。 从您的日志中可以清楚地看出您正在从空片段调用方法。在 onbackpresssed() 中,您调用了 getSelectedFragment(fragmentManager).getController() 而没有检查 getSelectedFragment() 是否给出 null 。尝试在 onBackPressed 中进行空检查。 对于上述问题,我得到一个片段为 null,已检查 @bpr10【参考方案3】:

对于上述问题,如上所述,Fragment 为 null。

所以,

BaseFragment frag = getSelectedFragment(fragmentManager);
if(frag  == null) return true;
BaseController fragmentController = frag.getController();

通过检查空引用解决了这个问题。

【讨论】:

以上是关于Fragment 的 GetTag 返回空对象引用的主要内容,如果未能解决你的问题,请参考以下文章

Android 保存 Fragment 引用及 getActivity() 为空问题

在 Activity 中调用 Fragment 方法会导致空指针异常

获取最后位置返回空对象引用错误

解决在v4包下的Fragment 里startActivityForResult,onActivityResult返回空数据问题

解决在v4包下的Fragment 里startActivityForResult,onActivityResult返回空数据问题

关于Android的setTag()方法和getTag()的一个问题