【问题标题】:Memory issue with ViewPagerViewPager 的内存问题
【发布时间】:2012-02-09 06:51:23
【问题描述】:

我目前正在开发一个使用 ViewPager 的应用程序,问题是我这样做的方式使其启动非常缓慢并且占用大量内存。

我正在像这样实现 pageradapter:

        public MyPagerAdapter(Context context) {
        views = new ArrayList<RelativeLayout>();
        views.add(new SliderLayout(context, "slide 8"));
        views.add(new SliderLayout(context, "slide 1"));
        views.add(new SliderLayout(context, "slide 2"));
        views.add(new SliderLayout(context, "slide 3"));
        views.add(new SliderLayout(context, "slide 4"));
        views.add(new SliderLayout(context, "slide 5"));
        views.add(new SliderLayout(context, "slide 6"));
        views.add(new SliderLayout(context, "slide 7"));
        views.add(new SliderLayout(context, "slide 8"));
        views.add(new SliderLayout(context, "Slide 1"));
    }

所有布局对象都包含一个带有 textView 的 FrameLayout 和一个 panel,其中包含一个带有本地 html 的 webview。所有布局都有独特的内容,在 SliderLayout 类被实例化时加载和膨胀。

我还尝试在 instantiateItem 方法中动态添加视图,但这只会使滚动更加狡猾,并且如果我滚动太快会出现 OutOfMemory 致命异常。

所以我的问题是,实现包含多个独特视图(但基于相同布局)的 ViewPager 的最佳方法是什么,这样它不会消耗太多内存并且启动速度更快?

【问题讨论】:

    标签: java android memory android-viewpager


    【解决方案1】:

    您必须在 instantiateItem() 中将视图附加到寻呼机(就像在常规适配器的 getView() 方法中那样)。在这种情况下,ViewPager 负责内存管理。查看 CompatibilityPackage 中的演示项目。实际上,您可以拥有数千页而没有任何延迟。

    @Override
    public Object instantiateItem(View collection, int position) {
        View v = layoutInflater.inflate(...);
        ...
        ((ViewPager) collection).addView(v,0);
        return tv;
    }
    
    @Override
    public void destroyItem(View collection, int position, Object view) {
        ((ViewPager) collection).removeView((TextView) view);
    }
    

    【讨论】:

    • 谢谢,您指的是哪个演示项目?我似乎找不到任何具体的东西,这对我最初的问题有帮助。
    • 查看 Support4Demos 文件夹中的 FragmentPagerSupport.java。有带有片段的 ViewPager,但是您可以使用 PagerAdapter 而不是 FragmetPagerAdapter 并将 getItem(int position) 方法替换为 public Object instantiateItem(ViewGroup container, int pos) 方法(就像您使用常规 ListView 的适配器一样)。对不起,我的错,我早把你的方法名弄错了。
    【解决方案2】:

    hm,我的想法是在 ViewPager 中捕获事件“onPageChanged()”并设置 页面更改后的 webview - 或者,作为示例预加载页面,以便您拥有 “滚动效果”:您执行以下操作:

    例如,您有 10 页。如果您的 viewpager 在第 0 页,那么您将实例化并加载第 0、1、2 页。如果您的 viewpager 在屏幕 4,那么您删除 webviews 在位置 0,1 和 7,8,9...

    这样你就不需要所有的webviews实例(webkit消耗大量内存) 并且有更多的内存。

    【讨论】:

    • 我不确定是不是这样,因为如果我禁用所有网页视图,它仍然会占用大量内存..
    • ViewPager myViewPager = "...在这里找到实例..." myViewPager.removeView(myWebkitView);通过这种方式,您可以确保 webkit 实例不在 ViewPager 对象的页面树中。
    • 谢谢,但我尝试从所有布局中删除所有 web 视图,但它仍然使用几乎相同数量的内存。我猜这是所有布局同时膨胀的方式或某种程度..
    猜你喜欢
    • 2012-06-12
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多