Android 解决fragment replace方法低效的问题

来源:互联网 发布:巨杉数据库 olap 编辑:程序博客网 时间:2024/04/20 12:29

刚开始学android的时候,对于fragment的切换问题,理所当然的使用FragmentTransaction中的replace方法来解决,但是这个方法时非常低效的,我们先来看官方文档对于这个方法的介绍:

replace

added in version 22.0.0
FragmentTransaction replace (int containerViewId,                 Fragment fragment,                 String tag)

Replace an existing fragment that was added to a container. This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here.

简单的翻译一下:替换一个已经被添加进容器的fragment,其本质与对所有已经添加进同一个id的容器(xml文件中的FrameLayout)的fragment调用remove(Fragment)方法然后调用add方法想要替换的fragment是相同的。

可以看出,调用replace的话,会先将原本处于容器中的fragment全部丢掉,然后再添加一个新的fragment,这样在每次replace的时候就会进行一次初始化,非常低效

     if (fragment == null) {            fragment = ActionFragment.newInstance();        }        FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();        transaction.replace(R.id.content_frame_card, fragment);        transaction.commit();

这段代码就是使用replace方法,我们在android monitor中看运行的时候疯狂点击切换的话内存会怎么样


可以看到,一开始内存的上升速度很快,虽然期间有GC工作,但是对于整个上升的趋势并没有很大的影响,后面停止点击内存趋于平稳,最后我手动调用了几次GC,内存迅速下降,虽然没有导致内存泄漏的问题,但是毫无疑问这个办法是很低效不可取的方法。

那么图和解决呢?我们可以参考点击打开链接这篇文章中的解决方法,采用hide和show来实现fragment的替换

public static void replaceFragment(FragmentManager manager, Fragment to, int fgmId) {        FragmentTransaction transaction = manager.beginTransaction();        //遍历隐藏所有添加的fragment        for (Fragment fragment : manager.getFragments()) {            transaction.hide(fragment);        }        if (!to.isAdded()) { //若没有添加过            transaction.add(fgmId, to).commit();        } else { //若已经添加            transaction.show(to).commit();        }    }


可以看到这一次在快速连续点击切换的情况下,内存没有明显的上升,上升趋势非常缓慢,且后面手动进行一次GC即可,这种方法很好的解决了replace的低效问题和切换时候的重叠问题

阅读全文
0 0