unbindDrawables at PagerAdapter Android Lollipop d

2019-09-11 23:39发布

I am trying to make Double View Pager and I override destroyItem function from my PagerAdapter just like in code bellow:

 @Override
public void destroyItem(ViewGroup container, int position, Object object)
{
    container.removeView((View) object);
    unbindDrawables((View) object);
    System.gc();
    object = null;
}

protected void unbindDrawables(View view)
{
    if (view instanceof ImageView)
    {
        Drawable drawable = ((ImageView) view).getDrawable();
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            Bitmap bitmap = bitmapDrawable.getBitmap();
            bitmap.recycle();
        }
        ImageWorker.cancelWork(((ImageView) view));
        ((ImageView) view).setImageResource(0);
        ((ImageView) view).setImageDrawable(null);
    }
    if (view.getBackground() != null)
    {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup)
    {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++)
        {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        if (!(view instanceof AdapterView<?>))
        {
            ((ViewGroup) view).removeAllViews();
        }
        //((ViewGroup) view).removeAllViews();
    }
}

Everything is OK on Android KitKat, Jelly Bean, even on Gingerbread and Ice Cream Sandwich, but when I try to test my app on API 21 and higher, I have Out of memory exception. When I debug my code, I can't see the problem. Can anyone help me ? Thanks.

1条回答
姐就是有狂的资本
2楼-- · 2019-09-11 23:52

I cannot see from the code that the imageview is removed from the view hierarchy, if the unbindDrawables is called on the imageView and not the viewgroup then it wont work to remove the imageview bitmap leak. I had a similar problem with out of memory that turned out to be the ImageView which prevented GC of byte[] from bitmap, and the only solution I found was to remove the ImageView from view hierarchy (and throw away the reference). It was NOT enough for me to do the following cleanup

    if (imageView.getBackground() != null) {
        imageView.getBackground().setCallback(null);
    }
    setImageBackground(imageView, null);
    imageView.setImageBitmap(null);
    imageView.setImageDrawable(null);

I also had lots of issues with Android Studio memory analyzer which this question is focused around.

Leaked unreferenced byte[] originally from bitmap but recycled() causing memory-leak (until activity stopped)

查看更多
登录 后发表回答