Android custom view Bitmap memory leak

前端 未结 2 1026
我在风中等你
我在风中等你 2020-12-05 01:09

I\'ve got a custom view in which I need to draw two bitmaps, one is a background, representing the image of a map and one is a pin which will be drawn on top/left position i

相关标签:
2条回答
  • 2020-12-05 01:25

    Something that marked me in your code is that you don't recycle all your bitmaps apparently. Here are a couple of code snippets that could help:

    bmp = getBitmapFromRessourceID(R.drawable.menu);
    ratio = (float)this.height/(float)bmp.getScaledHeight(canvas);
    temp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth()*ratio), (int) (bmp.getHeight()*ratio-10), false);
    bmp.recycle();
    bmp = temp;
    

    and:

    Bitmap temp = BitmapFactory.decodeResource(context.getResources(), resource, opts);
    Bitmap bmp = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(), temp.getHeight(), flip, true);
    temp.recycle();
    
    0 讨论(0)
  • 2020-12-05 01:48

    You obviously have a memory leak. Read how to avoid memory leaks and how to find memory leaks.

    Here is a your code refactored to use WeakReference:

    public class MyMapView extends View {
        private int xPos = 0;
        private int yPos = 0;
        private int space = 0;
    
        private WeakReference<Bitmap> resizedBitmap;
        private WeakReference<Bitmap> position;
        private WeakReference<Bitmap> mapBitmap;
    
        public void setMapBitmap(Bitmap value) {
            this.mapBitmap = new WeakReference<Bitmap>(value);
        }
    
        public MyMapView(Context context) {
            super(context);
        }
    
        public MyMapView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyMapView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public void init(Bitmap mapBitmap) {
            Paint paint = new Paint();
            paint.setFilterBitmap(true);
    
            int width = getMeasuredWidth();
            int height = getMeasuredHeight();
    
            resizedBitmap = new WeakReference<Bitmap>(Bitmap.createScaledBitmap(
                mapBitmap, width, height, true));
            position = new WeakReference(BitmapFactory.decodeResource(
                getContext().getResources(), R.drawable.position));
            space = (width - resizedBitmap.get().getWidth()) / 2;
        }
    
    //    public void destroy() {
    //        resizedBitmap.recycle();
    //        resizedBitmap = null;
    //        position.recycle();
    //        position = null;
    //        mapBitmap.recycle();
    //        mapBitmap = null;
    //    }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
                MeasureSpec.getSize(heightMeasureSpec));
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
    
            if (mapBitmap != null) {
                canvas.drawBitmap(resizedBitmap.get(), space, 0, null);
            }
    
            if (xPos != 0 && yPos != 0) {
                canvas.translate(xPos + space - position.get().getWidth() / 2, 
                    yPos - position.get().getHeight() / 2);
                canvas.drawBitmap(position.get(), new Matrix(), null);
    
            }
        }
    
        public void updatePosition(int xpos, int ypos) {
            xPos = xpos;
            yPos = ypos;
            invalidate();
        }
    }
    
    0 讨论(0)
提交回复
热议问题