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

本文探讨了在Android开发中遇到的Fragment引用保存和getActivity()返回null的问题。建议不在Activity.onCreate()中直接创建Fragment,而应在适配器中管理。同时,不应直接保存Fragment引用,而是利用FragmentManager找到相关Fragment。分析了FragmentPagerAdapter的工作原理,并提供了两种正确获取Fragment引用的方法:通过tag或者重写FragmentPagerAdapter的instantiateItem()方法。
摘要由CSDN通过智能技术生成

问题

做 Android 应用开发的小伙伴们大多都被 Fragment 坑过. 最近研究了其中常见的一种坑, 记录下来, 以免遗忘. 问题大体是这样的:
有时我们希望在 Activity 中保存所创建的 Fragment 的引用, 以便后续逻辑中做界面更新等操作. 如果页面中的 Fragment 都是静态的 (不会被 remove, hide 等), 则一般不会出啥问题. 如果是多个 Fragment 切换的场景, 就容易出现 getActivity() 为 null 等问题. 这种问题在使用 FragmentPagerAdapter 时尤其容易出现.
这里涉及两个问题: Fragment 的创建和 Fragment 引用的保存. 两个问题都有坑.

先放结论 (编程建议):
1. 不要在 Activity.onCreate() 中直接 new Fragment(). Fragment 的创建应尽量纳入 FragmentManager 的管理.
2. 尽量不要保存 Fragment 的引用. 在需要直接调用 Fragment 时, 使用 FragmentManager.findFragmentByTag() 等方法获取相关 Fragment 的引用.
3. 如果一定要保存 Fragment 引用, 则要谨慎选择获取引用的节点.

原因分析

以一段实际代码说明.
遇到主页需要左右滑动切换标签页的需求, 最常用的就是 ViewPager + FragmePagerAdapter 方案了. 很多小伙伴可能会这样写 (示例代码1):

public class TabChangeActivity extends AppCompatActivity {
   

    private ArrayList<Fragment> mFragmentList;
    private ViewPager mViewPager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tab_fragment_sample);
        mFragmentList = new ArrayList<>(3);
        mFragmentList.add(new Fragment1());
        mFragmentList.add(new Fragment2());
        mFragmentList.add(new Fragment3());
        mViewPager = (ViewPager) findViewById(R.id.view_pager);
        mViewPager.setAdapter(new SlidePagerAdapter(getSupportFragmentManager()));
    }

    private class SlidePagerAdapter extends FragmentPagerAdapter {
   

        public SlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentList.size();
        }
    }
}

上例是一个最简单的标签页切换界面写法, 布局中只有一个 ViewPager, 就不再贴出了.
但这段代码是存在隐患的.
这里首先复习一下 Activity 管理 Fragment 的方式. 在代码中动态显示 Fragment 时, 大体流程如下:

private void showFragment1() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    // 查看 fragment1 是否已经被添加
    Fragment1 fragment1 = (Fragment1) fragmentManager.findFragmentByTag(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值