5

我需要用 5 张幻灯片在 Android 中创建 ViewPager,每张都由图像和文本组成。我有一个包含图像资源的数组:

  private static final int[] images = {R.drawable.tutorial_step_01, R.drawable.tutorial_step_02, R.drawable.tutorial_step_03, R.drawable.tutorial_step_04, R.drawable.tutorial_step_05, R.drawable.tutorial_step_06};

然后我创建适配器:

@Override
    public Object instantiateItem(ViewGroup container, int position) {

        LinearLayout tv = (LinearLayout) inflater.inflate(R.layout.tut_slide, null);
        TextView title = (TextView) tv.findViewById(R.id.tut_title);
        title.setText(getResources().getText(titles[position]));
        TextView content = (TextView) tv.findViewById(R.id.tut_content);
        ImageView image = (ImageView) tv.findViewById(R.id.tut_image);

        slide_image = BitmapFactory.decodeResource(getResources(), images[position]);
        image.setImageBitmap(slide_image);
        content.setText(getResources().getText(contents[position]));
        ((ViewPager) container).addView(tv, 0);
        return tv;
    }



    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        ((ViewPager) container).removeView((LinearLayout) object);

//
}

麻烦的是,在我选择另一个页面后,android 不想收集图像。因此,经过 10-15 次更改后,它会出现 OutOfMemory 异常。然后我添加到初始化行

if (slide_image!= null) {
            slide_image.recycle();
            System.gc();
        }

而且效果很好!但除了一件事:我有黑屏而不是第一张图像,经过几次翻转后被真实图像取代。所以我不知道如何处理这种内存泄漏

4

4 回答 4

6

好吧,我终于解决了这个问题。我遇到了一个非常相似的案例,因为我已经看到了很多与同一问题相关的问题,所以我选择了这个问题,因为它还没有得到回答。不仅应该在超过时PagerAdapter调用该方法,而且在发生屏幕旋转时也应该调用该方法,但它不会,因此必须强制这样做......要实现它,您只需将适配器设置为空关于活动的或方法。destroyItemoffLimitScreenPageLimitonStoponDestroy

@Override protected void onDestroy(){
    pager.setAdapter(null);
}

干杯!

于 2015-05-05T00:54:27.360 回答
1

目前尚不清楚您使用的是什么,但我遇到了类似的问题。

我假设您正在使用 FragmentPagerAdapter。

当您使用该适配器滚动时,它不会破坏视图和缓存之外的页面。如果 FragmentPageAdapter 使用的 Fragment 中存在 ImageView,OOM 是不可避免的

只需将适配器的扩展更改为

FragmentStatePagerAdapter

这将销毁未使用的片段,并为新片段留出更多可用内存。

它仍然不完美,我发现有时我可以滚动比垃圾收集器拾取被破坏的位图更快,但它非常接近。

如果我想改进它,我会覆盖destroyItem,然后从imageview 中获取正在使用的位图并回收位图。

回收 ImageView 的 Bitmap

于 2013-05-15T07:25:46.677 回答
0

这种行为不应该与内存泄漏有关。看起来它与您在 viewpager 更新生命周期内何时以及如何回收位图有关。尝试在初始化时手动调用 onPageSelected() 或 notifyDatasetChanged()。

此解决方案可能无法完全解决问题,但请尝试一下。你的解释很难说清楚。

于 2012-11-13T17:31:45.027 回答
0

在我的情况下,我在 ViewPager 中有 31 页。我用这个:

 @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {

        if(dbCon!=null)
            dbCon.close();

        ViewPager viewPager = (ViewPager)container;
        View view = (View) object;
        viewPager.removeView(view);
    }

一切正常。阿罕杜里拉。

于 2020-11-13T11:18:01.973 回答