Forum Xamarin.Forms

Announcement:

The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Maps marker update causes out of memory exception

marius1337marius1337 NOMember ✭✭
edited May 2017 in Xamarin.Forms

Hi,
I am adding custom markers to my map (GoogleMap in this case). I want my markers to adjust in size based on zoom level. My code is working, and I am able to zoom in and out 15-20 times, and the markers are updated. However, eventually an Out Of Memory exception is thrown, which makes me believe I am forgetting something.

I am initializing the zoom listener method like this:

            map.CameraChange += delegate (object sender, GoogleMap.CameraChangeEventArgs e)
            {
                UpdateMarkers(e.Position.Zoom);
            };

And this triggers my UpdateMarkers method:

private void UpdateMarkers(float zoom)
    {
        int dimension = (int)(zoom * zoom) / (AppHelper.ScreenWidth / 300);
        if (dimension == currentDimension)
            return;
        currentDimension = dimension;
        map.Clear();
        if (null == icons || icons.Count == 0)
            InitializeIcons();

        var paintFill = new Paint(PaintFlags.AntiAlias);
        paintFill.SetStyle(Paint.Style.Fill);

        var paintStroke = new Paint(PaintFlags.AntiAlias);
        paintStroke.SetStyle(Paint.Style.Stroke);
        paintStroke.Color = new Android.Graphics.Color(0, 0, 0);

        Typeface typeface = Typeface.CreateFromAsset(this.Context.Assets, "Fonts/myfont.ttf");

        foreach (var pin in customPins)
        {
            string text = pin.Pub.Price + ",-";
            paintStroke.SetTypeface(typeface);
            paintStroke.TextSize = GetTextSize(paintStroke, dimension, text);
            paintStroke.StrokeWidth = paintStroke.TextSize / 30f;
            paintFill.SetTypeface(typeface);
            paintFill.TextSize = GetTextSize(paintFill, dimension, text);
            paintFill.Color = GetTextColor(pin.Pub.Event);
            string iconName = GetIconName(pin.Pub.Event, pin.Pub.Liter);
            var bitmap = icons[iconName].Copy(icons[iconName].GetConfig(), true); //icons[] is a dictionary of all bitmaps I use
            var scaledBitmap = ScaleBitmap(bitmap, dimension); //returns a new, scaled bitmap. Both bitmaps used are disposed later
            var rect = new Rect();
            paintFill.GetTextBounds(text, 0, text.Length, rect);
            float textWidth = paintFill.MeasureText(text);
            float y = rect.Height();
            float bitmapWidth = scaledBitmap.Width;
            float x = (bitmapWidth - textWidth) / 2;
            var canvas = new Canvas(scaledBitmap);
            canvas.DrawText(text, x, y, paintFill);
            canvas.DrawText(text, x, y, paintStroke);
            var markerBitmap = BitmapDescriptorFactory.FromBitmap(scaledBitmap); //This is where it usually crashes
            var marker = new MarkerOptions();
            marker.SetPosition(new LatLng(pin.Pin.Position.Latitude, pin.Pin.Position.Longitude));
            marker.SetTitle(pin.Pin.Label);
            marker.SetSnippet(pin.Pin.Address);
            marker.SetIcon(markerBitmap);
            map.AddMarker(marker);
            rect.Dispose();
            bitmap.Recycle();
            bitmap.Dispose();
            scaledBitmap.Recycle();
            scaledBitmap.Dispose();
            markerBitmap.Dispose();
            canvas.Dispose();
            marker.Dispose();
        }
        paintFill.Dispose();
        paintStroke.Dispose();
        typeface.Dispose();
    }

Is there any visible issues here? I figured if I always dispose my markers after use, my memory would stay somewhat the same.
I have seen posts to set configuration to allow more memory or something, but I dont think its any point if it will just delay a crash. Have I misunderstood how this works?

Sign In or Register to comment.