关于viewpager常见的泄漏

在一个页面中 如果有用到tab,有需要进行fragment的切换,经常就看到了
private var fragments = arrayListOf<Fragment>()



private fun initFragment() {
        arguments?.let {
            hopeToPosition = it.getInt(IntentConstant.MAIN_PAGE_GO, 0)
            workoutType = it.getInt(IntentConstant.WORKOUT_PAGE_GO, 0)
            challengesTabId = it.getLong(IntentConstant.CHALLENGES_TAB_ID, 0L)
        }

        val fragmentHome = ARouter.getInstance().build(RrouterConstant.HOME_MAIN_FRAGMENT).navigation() as Fragment
        val fragmentWorkout = SportFragment.newInstance()
        val fragmentChallenges = EntertainmentFragment.newInstance()

        fragments.add(fragmentHome)
        fragments.add(fragmentWorkout)
        fragments.add(fragmentChallenges)


        BarUtils.setStatusBarLightMode(requireActivity().window, true)
        fromFragment = fragmentHome
        val transaction: FragmentTransaction = requireActivity().supportFragmentManager.beginTransaction()



        if (hopeToPosition == 1) {
            fromFragment = fragmentWorkout
            (fromFragment as SportFragment).changeTab(workoutType)
            dataBinding.navigationLaunch.menu.getItem(1).isChecked = true
            tabIndex = hopeToPosition
        }


        transaction.replace(R.id.vp_fragment, fromFragment!!)
        transaction.commit()
    }



    private fun switchFragment(from: Fragment?, to: Fragment?, isResume: Boolean = false) {
        if (from !== to) {
            val manger: FragmentManager = requireActivity().supportFragmentManager
            val transaction = manger.beginTransaction()
            if (!to!!.isAdded) {
                if (from != null) {
                    transaction.hide(from)
                }
                if (to != null) {
                    if (isResume) {
                        transaction.add(R.id.vp_fragment, to).commitAllowingStateLoss()
                    } else {
                        transaction.add(R.id.vp_fragment, to).commit()
                    }
                }
            } else {
                if (from != null) {
                    transaction.hide(from)
                }
                if (to != null) {
                    if (isResume) {
                        transaction.show(to).commitAllowingStateLoss()
                    } else {
                        transaction.show(to).commit()
                    }
                }
            }
        }
        fromFragment = to
    }

但是这样比如在 mainfragment就就强引用了子fragment,这种强应用leakcanary不会报异常,但是Android studio的profile会报泄漏

修复方案

private val fragmentTags = mutableMapOf<Int, String>()




    private fun switchFragment(position: Int) {
        val manger: FragmentManager = requireActivity().supportFragmentManager
        val transaction = manger.beginTransaction()
        val tag = "fragment_$position"
        LogUtils.d("linlian mainfragment switchFragment $position")
        // 查找已存在的 Fragment
        val existingFragment = manger.findFragmentByTag(tag)
        val newFragment = when (position) {
            0 -> ARouter.getInstance().build(RrouterConstant.HOME_MAIN_FRAGMENT)
                .navigation() as Fragment

            1 -> SportFragment.newInstance()
            else -> EntertainmentFragment.newInstance()
        }

        if (existingFragment != null) {
            transaction.show(existingFragment)
        } else {
            transaction.add(R.id.vp_fragment, newFragment, tag)
        }
        fragmentTags[position] = tag
        // 隐藏其他 Fragment
        manger.fragments.forEach { frag ->
            LogUtils.d("linlian MainFragment hide $frag,tag =${frag.tag},valuse=${fragmentTags.values}")
            if (frag.tag != null && frag.tag != tag && fragmentTags.values.contains(frag.tag)) {
                LogUtils.w("linlian MainFragment hide frag !!!$frag")
                transaction.hide(frag)
            }
        }
        transaction.commit()
    }

这样就可以不直接引用fragment

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值