проблема с памятью с гугл картой и оверлеями!

Я рисую несколько оверлеев на карте Google. Если я слишком много перемещаюсь по карте, я получаю такую ​​ошибку:

10-15 14: 43: 43.020: ERROR / dalvikvm-heap (299): 32768-байтное внешнее выделение слишком велико для этого процесса. 10-15 14: 43: 43.020: ERROR / GraphicsJNI (299): VM не позволяет нам выделить 32768 байт 10-15 14: 43: 43.260: ERROR / AndroidRuntime (299): FATAL EXCEPTION: main 10-15 14: 43: 43.260: ERROR / AndroidRuntime (299): java.lang.OutOfMemoryError: размер растрового изображения превышает бюджет виртуальной машины 10-15 14: 43: 43.260: ERROR / AndroidRuntime (299): at android.graphics.Bitmap.nativeCreate (собственный метод) 10-15 14: 43: 43.260: ОШИБКА / AndroidRuntime (299): в android.graphics.Bitmap.createBitmap (Bitmap.java:468)

В своей куче я вижу, что израсходовано менее 30%.

Может кто-нибудь мне помочь ? Есть выход? Спасибо.

///////////////////////////////////////////////

public void draw (Canvas canvas, MapView mapv, логическая тень) {

    BusLoc.myMapView.destroyDrawingCache ();
    super.draw(canvas, mapv, shadow);

    Paint mPaint = new Paint();
    mPaint.setDither(true);
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(2);

    /////////////////////////////get the lat/long info/////////////////////////////////////

    BusLoc.mapCenter= BusLoc.myMapView.getMapCenter();
    int latCenter = BusLoc.mapCenter.getLatitudeE6();
    int longCenter = BusLoc.mapCenter.getLongitudeE6();
    int latSpan = BusLoc.myMapView.getLatitudeSpan();
    int longSpan = BusLoc.myMapView.getLongitudeSpan();
    int latMax = latCenter + (latSpan / 2);
    int latMin = latCenter - (latSpan / 2);
    int longMax = longCenter + (longSpan / 2);
    int longMin = longCenter - (longSpan / 2);

    ///////////////////////////////////////////////////////////////////////////////////////


    Log.d("MyOverlay","OnDraw");

    int in=0;
    for(in=0;in<ind-1;in++)
    {
        if (ah1[in][0] ==0 ||(ah1[in+1][0]==0)) break;
        if((ah1[in][0] !=0) &&(ah1[in+1][0]!=0))
        {
            GeoPoint gP1 = new GeoPoint((int)(ah1[in][0]*1e6),(int)(ah1[in][1]*1e6)); //lat,lng
            GeoPoint gP2 = new GeoPoint((int)(ah1[in+1][0]*1e6),(int)(ah1[in+1][1]*1e6));



            Point p1 = new Point();
            Point p2 = new Point();

            Path path = new Path();

            Projection projection = BusLoc.myMapView.getProjection();
            projection.toPixels(gP1, p1);
            projection.toPixels(gP2, p2);

            path.moveTo(p2.x, p2.y);
            path.lineTo(p1.x,p1.y);

            if((((ah1[in][0]<=latMax)&&(ah1[in][0]>=latMin))&&((ah1[in][1]<=longMax)&&(ah1[in][1]>=longMin))) || (((ah1[in+1][0]<=latMax)&&(ah1[in+1][0]>=latMin))&&((ah1[in+1][1]<=longMax)&&(ah1[in+1][1]>=longMin))) )
            {
                canvas.drawPath(path, mPaint);
            }

            Log.d("MyOverlay","drawn: "+gP1.toString()+":"+gP2.toString());
        }
    }
   // BusLoc.myMapView.destroyDrawingCache ();
}

person Ahsan    schedule 15.10.2010    source источник
comment
как вы видите, что используется только 30% вашей кучи? растровые изображения не используют кучу jvm, а внутреннюю кучу. См. Мой ответ на stackoverflow.com/questions/3238388/   -  person Mathias Conradt    schedule 15.10.2010
comment
спасибо @Mathias Lin ... тоже попробую вашу идею ... и расскажу, как это помогает ... кстати ... просто чтобы вы знали ... Я был взволнован этой штукой с кучей, потому что раньше у меня был неэффективный разреженный массив кодирование, которое означало использование кучи 90% или более ... а теперь только 30%, я ожидал, что это будет лучше!   -  person Ahsan    schedule 15.10.2010
comment
@ Матиас Лин: это то, что я получаю до ошибки !!   -  person Ahsan    schedule 16.10.2010
comment
10-16 13: 33: 10.548: INFO / System.out (1596): alloc: 6.912223815917969: available: 7.0703125 Подскажите, что я могу сделать. Спасибо.   -  person Ahsan    schedule 16.10.2010
comment
и это ... 10-16 13: 40: 01.658: INFO / System.out (1661): alloc: 7.0171661376953125: доступно: 7.10546875   -  person Ahsan    schedule 16.10.2010
comment
Итак, около 50% собственной кучи используется .. как уменьшить использование?   -  person Ahsan    schedule 16.10.2010
comment
Замечание: не рисуйте Paths, от этого вы не получите никакого аппаратного ускорения. используйте вместо этого drawLines(). Он использует массив float вместо Paths и намного быстрее с точки зрения производительности.   -  person ubuntudroid    schedule 05.03.2013


Ответы (1)


Вы должны явно рисовать только те наложения, которые видны на вашем экране, если не все наложения нарисованы независимо от того, видите вы их или нет, это не только вызывает проблемы с памятью, но и делает перемещение карты очень медленным на не очень хороших устройствах.

MapController mapControl = map.getController();
        GeoPoint mapCenter = map.getMapCenter();
        int latCenter = mapCenter.getLatitudeE6();
        int longCenter = mapCenter.getLongitudeE6();
        int latSpan = map.getLatitudeSpan();
        int longSpan = map.getLongitudeSpan();
        int latMax = latCenter + (latSpan / 2);
        int latMin = latCenter - (latSpan / 2);
        int longMax = longCenter + (longSpan / 2);
        int longMin = longCenter - (longSpan / 2);

Напишите какой-нибудь код, чтобы определить, находится ли ваша достопримечательность в пределах этого диапазона просмотра, если она нарисована, если нет.

Я также предполагаю, что вы используете небольшой индикатор наложения, они могут быть очень маленькими и с низким разрешением без потери качества.

person blindstuff    schedule 15.10.2010
comment
Большое спасибо @blindstuff .. Я очень ценю помощь. Я буду работать над этой идеей прямо сейчас и попробую посмотреть, поможет это или нет. Спасибо. - person Ahsan; 15.10.2010
comment
Привет ... Извините, он не работает ... он задерживает ошибку до гораздо большего ... но после того, как иногда возникает та же проблема. Я прикрепляю к задаче код отрисовки. ! - person Ahsan; 15.10.2010
comment
Странно, ваш код выглядит нормально. Я бы попытался нарисовать рисование вместо линии, просто любое случайное изображение, если вы хотите рисовать в начальной и конечной точке, чтобы увидеть, есть ли ошибка в создании линии с помощью краски или на самой карте. - person blindstuff; 15.10.2010
comment
@ Blindstuff: код не очень удобен для меня ... я имею в виду ... потому что я рисую линии ... даже если две точки не в поле зрения ... линия может быть внутри вида ... и поскольку рисование линий очень важно ... так что ... я не могу использовать ваш код ... но спасибо за образец кода, я могу использовать его для наложения ... всего ... (а не рисования линий) .. :) - person Ahsan; 16.10.2010
comment
Вы выяснили, в чем проблема? Вы должны рисовать только в том случае, если хотя бы одна из точек находится на экране, но не рисуйте линию, если на экране нет ни одной точки. У меня есть приложение, в котором наложено около 7000 точек, и только из-за этого изменения оно превратилось из несовершенного в идеальное. - person blindstuff; 18.10.2010