android – 仔细检查片段视图持有者模式是否正确实现

android – 仔细检查片段视图持有者模式是否正确实现,第1张

概述由于内存泄漏,我一直在重新编写代码.代码是应用程序帮助部分的一部分,我们使用FragmentActivity和FragmentPageAdapter来允许用户滑动不同的帮助屏幕.下面的每个片段SectionFragment类包括一个图像,一些标题文本和正文. 内存泄漏表现自己,因为每次在Fragment中调用onCreateView时,新视图都会膨胀. public class SectionFr 由于内存泄漏,我一直在重新编写代码.代码是应用程序帮助部分的一部分,我们使用FragmentActivity和FragmentPageAdapter来允许用户滑动不同的帮助屏幕.下面的每个片段SectionFragment类包括一个图像,一些标题文本和正文.

内存泄漏表现自己,因为每次在Fragment中调用onCreateVIEw时,新视图都会膨胀.

public class SectionFragment extends Fragment {    private ImageVIEw imgvw;    private TextVIEw headerTxvw;    private TextVIEw bodyTxvw;    public int[][] content;            protected int pageIDx;    public SectionFragment(int IDx,int[][] content ){        super();        pageIDx = IDx;        this.content = content;    }    protected int getPageIDx() {        return pageIDx;    }    protected Drawable getimageDrawable() {        return getResources().getDrawable( content[pageIDx][0] );    }    protected String getheaderText() {        return getResources().getString( content[pageIDx][1] );    }    protected String getSubeaderText() {        return getResources().getString( content[pageIDx][2] );    }    protected voID loadVIEw( VIEw vw ) {        imgvw = (ImageVIEw)vw.findVIEwByID( R.ID.top_img );        headerTxvw = (TextVIEw)vw.findVIEwByID( R.ID.header_txt );        bodyTxvw = (TextVIEw)vw.findVIEwByID( R.ID.body_txt );        imgvw.setimageDrawable( getimageDrawable() );        headerTxvw.setText( getheaderText() );        bodyTxvw.setText( getSubeaderText() );    }    @OverrIDe    public VIEw onCreateVIEw(LayoutInflater inflater,VIEwGroup container,Bundle savedInstanceState) {        VIEw vw = inflater.inflate( R.layout.help_fragment,null );        loadVIEw( vw );        return vw;    }}

我还是Fragments的新手,并不是原始编码工作的一部分,所以我不确定我的解决方案是否正确,但它类似于我在List活动中多次实现的视图持有者模式.我真的很感激有关以下实施的任何反馈,所以我会更加放心,这是正确的.

public class SectionFragment extends Fragment {static private class VIEwHolder {    ImageVIEw imgvw;    TextVIEw headerTxvw;    TextVIEw bodyTxvw;}public int[][] _content;protected int _pageIDx;public SectionFragment( int IDx,int[][] content ){    super();    _pageIDx = IDx;    _content = content;}protected int getPageIDx() {    return _pageIDx;}protected Drawable getimageDrawable() {    return getResources().getDrawable( _content[_pageIDx][0] );}protected String getheaderText() {    return getResources().getString( _content[_pageIDx][1] );}protected String getSubeaderText() {    return getResources().getString( _content[_pageIDx][2] );}protected voID loadVIEw( VIEw vw ) {    _holder.imgvw.setimageDrawable( getimageDrawable() );    _holder.headerTxvw.setText( getheaderText() );    _holder.bodyTxvw.setText( getSubeaderText() );}private VIEw _vw;private VIEwHolder _holder;@OverrIDepublic VIEw onCreateVIEw(LayoutInflater inflater,Bundle savedInstanceState) {    if ( _vw == null ) {        _vw = inflater.inflate( R.layout.help_fragment,null );        _holder = new VIEwHolder();        _holder.imgvw = (ImageVIEw)_vw.findVIEwByID( R.ID.top_img );        _holder.headerTxvw = (TextVIEw)_vw.findVIEwByID( R.ID.header_txt );        _holder.bodyTxvw = (TextVIEw)_vw.findVIEwByID( R.ID.body_txt );        _vw.setTag( _holder );    } else {        VIEwParent oldparent = (VIEwParent)_vw.getParent();        if ( oldparent != container ) {            ((VIEwGroup)oldparent).removeVIEw( _vw );        }        _holder = (VIEwHolder)_vw.getTag();    }    loadVIEw( _vw );    return _vw;}}

我没有包含与此代码相关的其他类,特别是FragmentActivity和FragmentPagerAdapter,因为它们似乎正确实现,但如果请求我也可以包含它们.

解决方法 一般来说,AndroID应用程序中的内存泄漏

你确定它是在泄漏内存而不仅仅是延迟垃圾收集吗?您是否在应用程序上运行eclipse内存分析器插件?它通常可以准确显示泄漏发生的位置.

片段vIEwpager及其回收(或缺乏)

我对片段寻呼机内存泄漏/增加的第一个猜测是拥有一个动态适配器. fragmentpageradapter非常愚蠢,无法很好地处理更改.

据我所知,从源头看它永远不会破坏碎片,即使你将数量从5改为4(第五个碎片将保留在碎片管理器中).这是因为它被分离而不是被破坏.但是,当它们位于页边距之外时,fragmentstatepageradapter将销毁它们.

从长远来看,所有这些都不会导致内存泄漏,因为当片段管理器稍后清除片段时,这些片段将被清除.然而,它可以相当多地增加内存使用(可能导致outofmemoryerror).

确实每次创建片段时都会创建一个新视图(如果将retaininstance设置为true,则通常会创建新视图),但除非您使用FragmentStatePagerAdapter,每个片段只应出现一次,因为正常的寻呼机适配器会分离并附加相同的片段来自片段管理器.在任何情况下,视图将在活动被销毁后处理,除非您保留对它的引用.

你似乎确实在你的课程中保留了对视图的引用,这是我通常试图避免的.我更喜欢在需要时使用getVIEw().findVIEwByID(),但在这种情况下,我认为gc会找到并删除成员引用.这一切都取决于你当然是否泄漏了那些参考文献.

在片段寻呼机中的观察者

您不应该尝试像片段中的视图符号那样执行某些 *** 作.在这个例子中它可能不会受到伤害,但我看不到你从中获得任何东西.只需在oncreatevIEw中膨胀视图并设置值并完成它.

列表视图中没有回收视图,因此VIEwHolder模式没有任何意义,只会因为悬空引用而引入内存泄漏或延迟垃圾收集.

视图不会被重用,即使它们可以在您使用过的某些父级技巧中进行.这应该只是作为最后的出路.如果在流程中有任何关闭,它可能会导致可怕的泄漏.

如果有人能够合理使用它,请纠正我.

关于VIEwHolder的旁注

我实际上不会使用vIEwholder,除非我真的需要它甚至在ListvIEw中.我已经看到这些标签导致真正令人讨厌的内存泄漏,例如一些游标适配器,我会在尝试引用保存之前考虑使我的行布局更简单. FindvIEwbyID在良好的布局中不会那么昂贵.

总结

以上是内存溢出为你收集整理的android – 仔细检查片段视图持有者模式是否正确实现全部内容,希望文章能够帮你解决android – 仔细检查片段视图持有者模式是否正确实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1131340.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存