从视图持有人中的路径加载位图时,内存泄漏



我现在试图找出很长时间的原因,为什么我在listView的视图中得到了此内存泄漏。

奇怪的部分是,将图像视图(coveriv)设置为((bitmapdrable)_activity.resources.getDrawable(resource.drawable.splash))。位图,根本没有问题。

当我使用等待ImageLoader.decodesampledbitmapmapfromresourceasync(localimagelocation,imgwidth,imgheight)时,每次我在ListView

中滚动时都会有一个巨大的内存泄漏

我尝试使用内存分析仪工具找到参考,但没有……尽管Mat说问题是位图

public void ImageLoaded(string localImageLocation)
{
            int screenWidth = _activity.Resources.DisplayMetrics.WidthPixels;
            int imgWidth = screenWidth - (int)ConvertDpToPix (32f);
            int imgHeight = (int)(ConvertDpToPix(206f));
            BundleProgress.Visibility = ViewStates.Gone;
            if (CoverIv.Drawable != null)
            {
                            ((BitmapDrawable)CoverIv.Drawable).Bitmap.Recycle ();
                            ((BitmapDrawable)CoverIv.Drawable).Bitmap.Dispose ();
                            CoverIv.SetImageDrawable (null);
            }
            CoverIv.SetImageBitmap 
            (
            //MEMORYLEAK:   await ImageLoader.DecodeSampledBitmapFromResourceAsync  (localImageLocation, imgWidth, imgHeight)
                ((BitmapDrawable)_activity.Resources.GetDrawable(Resource.Drawable.splash)).Bitmap
            );

Imageloader类中的方法:

        public static async Task<Bitmap> DecodeSampledBitmapFromResourceAsync (String path,int reqWidth, int reqHeight)
            {
            // First decode with inJustDecodeBounds=true to check dimensions of the image
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.InJustDecodeBounds = true;
            Bitmap bitmap = await BitmapFactory.DecodeFileAsync(path, options);
            // Calculate inSampleSize
            options.InSampleSize = CalculateInSampleSize(options, reqWidth,
                reqHeight);
            // Decode bitmap with inSampleSize set
            options.InJustDecodeBounds = false;
            options.InPreferredConfig = Bitmap.Config.Argb8888;
            //options.InDither = true;
            return await BitmapFactory.DecodeFileAsync(path, options);
        }
      public static int CalculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
        {
            // Raw height and width of image
            float height = options.OutHeight;
            float width = options.OutWidth;
            double inSampleSize = 1D;
            if (height > reqHeight || width > reqWidth)
            {
                int halfHeight = (int)(height / 2);
                int halfWidth = (int)(width / 2);
                // Calculate a inSampleSize that is a power of 2 - the decoder will use a value that is a power of two anyway.
                while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth)
                {
                    inSampleSize *= 2;
                }
            }
            return (int)inSampleSize;
        }

适配器:

public override View GetView (int position, View convertView, ViewGroup parent)
    {
        BaseBundelVO bundle = _bundles [position];
        DSBundleListItem bundleHolder = null;
        DSBundleArchiveItem archiveHolder = null;
        int type = GetItemViewType(position);
        if (convertView == null)
        {
            bundleHolder = new DSBundleListItem (_activity.ApplicationContext);
            archiveHolder = new DSBundleArchiveItem (_activity.ApplicationContext);
            switch (type) 
            {
            case 0:
                convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleListItem, null);
                bundleHolder.IconIv = convertView.FindViewById<ImageView> (Resource.Id.iconIv);
                bundleHolder.CoverIv = convertView.FindViewById<ImageView> (Resource.Id.coverIv);
                bundleHolder.CoverTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverTitleTv);
                bundleHolder.CoverSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.coverSubTitleTv);
                bundleHolder.BundleProgress = convertView.FindViewById<ProgressBar> (Resource.Id.bundleProgress);
                convertView.Tag = bundleHolder;
                break;
            case 1:
                convertView = _activity.LayoutInflater.Inflate (Resource.Layout.dsBundleArchiveItem, null);
                archiveHolder.ArchiveTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveTitleTv);
                archiveHolder.ArchiveSubTitleTv = convertView.FindViewById<TextView> (Resource.Id.archiveSubTitleTv);
                convertView.Tag = archiveHolder;
                break;
            }
        } 
        else 
        {
            switch (type) 
            {
            case 0:
                bundleHolder = (DSBundleListItem)convertView.Tag;
            break;
            case 1:
                archiveHolder = (DSBundleArchiveItem)convertView.Tag;
            break;
            }
        }
        switch (type) 
        {
        case 0:
            bundleHolder.CoverTitleTv.Text = bundle.Title;
            bundleHolder.CoverSubTitleTv.Text = bundle.SubTitle;
            bundleHolder.CoverIv.SetImageDrawable (null);
            bundleHolder.IconIv.SetImageDrawable (null);
            bundleHolder.LoadImage(bundle.CoverImageLocation,bundle.Icon);
            break;
        case 1:
            archiveHolder.ArchiveTitleTv.Text    = "Archief";
            archiveHolder.ArchiveSubTitleTv.Text = "Bekijk onze eerder verschenen publicaties";
            break;
        }
        return convertView;
    }
    public void SetData(List<BaseBundelVO> bundles)
    {
        _bundles.Clear ();
        _bundles.AddRange(bundles);
    }

使用图像时使用毕加索库,它起作用了!

我也推荐Pisasso库。这是链接:http://square.github.io/picasso/

它立即从网络中检索图像并在本地缓存。

导入毕加索库后,您必须简单地将此行添加到您的代码中:

Picasso.with(context).load("*your url*").into(*your image view*);

您也可以加载本地图像!

Picasso.with(context).load("file:///android_asset/image.png").into(*your image view*);

希望这会有所帮助,

请尝试我的代码。我认为您的解码有问题:

private Bitmap DisplayRotatedPhoto(Uri path) {
    String filePath = path.toString().substring(8);
    Bitmap oriented = null;
    BitmapFactory.Options bitmapFactoryOptions = new BitmapFactory.Options();
    bitmapFactoryOptions.inJustDecodeBounds = true;
    int REQUIRED_SIZE = 100;
    int width_tmp = bitmapFactoryOptions.outWidth, height_tmp = bitmapFactoryOptions.outHeight;
    int scale = 2;
    while (true) {
        if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
            break;
        width_tmp /= 2;
        height_tmp /= 2;
        scale++;
      }
    BitmapFactory.Options bitmapFactoryOptions2 = new BitmapFactory.Options();
    bitmapFactoryOptions2.inSampleSize = scale;
    Bitmap bmp = BitmapFactory.decodeFile(filePath, bitmapFactoryOptions2);
}

最新更新