Hilfe für java.lang.OutOfMemoryError Problem

  • Antworten:6
Hendrix
  • Forum-Beiträge: 22

24.11.2016, 16:22:17 via Website

Hallo :)

ich weiß dieses Problem gibts wahrscheinlich oft wenn man mit Bitmaps arbeitet und hab auch schon Lösungsanstätze gefunden doch bei mir klappt das irgendwie nicht so wie erhofft:
erstmal zum Code

Bitmap erzeugung:
java class trapViews:

@Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int x = 20;
        Random r = new Random();
        int i1 = r.nextInt(900 - 200) + 200;
        rnd = new Random();
        //Linke Seite

        System.gc();

        Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.stachelnstart);
        Bitmap resizedBitmap = Bitmap.createScaledBitmap(image, i1, 300, true);
            float left = (float) 0;
            float top = (float) (getHeight() - resizedBitmap.getHeight());
            canvas.drawBitmap(resizedBitmap, left, top, paint);


        //rechte Seite
       Bitmap images = BitmapFactory.decodeResource(getResources(), R.drawable.stachelnstart1);
        Bitmap resizedBitmaps = Bitmap.createScaledBitmap(images, getWidth()-resizedBitmap.getWidth()-OwlHole, 300, true);
            float left1 = (float) (getWidth() - resizedBitmaps.getWidth());
            float top1 = (float) (getHeight() - resizedBitmaps.getHeight());
            canvas.drawBitmap(resizedBitmaps, left1, top1, paint);

}

}

erzeugt auf der rechten sowie linken seite jeweils 1 mal das Bitmap stachelnstart^^
dies wird jz alle 5 sec durch einen handler in meiner MainActivity aufgerufen:

 final Handler h = new Handler();
Runnable r = new Runnable()
{
    public void run()
    {
        System.gc();
        traps();
        h.postDelayed(this,5000);//Handler neustarten

    }
};

private void traps() {

    container = (ViewGroup) findViewById(R.id.container);
    trapViews tv = new trapViews(this);
    container.addView(tv,
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT);
    //tV.setImageCount(8);
   h.postDelayed(r,5000);
}

es macht das was es machen soll nämlich wird alle 5 sec rechts und links mit einer zufälligen Länge ein Bitmap produziert. Doch schon beim ersten durchlauf hängt die app kurz dann wirds produziert und das wird von mal zu mal schlimmer bis Sie abstürzt und den Fehler java.lang.OutOfMemoryError: Failed to allocate a 916812 byte allocation with 267632 free bytes and 261KB until OOM anzeigt.

Im Code hab ich den Garbage Collecter (System.gc()) verwendet was aber genauso wenig hilft wie image.recycle();

hat hierfür jemand eine lösung?

übrigens https://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap hab ich mir durchgelesen und ausprobiert aber hat auch nicht so geklappt wie ich mir das vorgestellt habe ^^

Vielen Danke schonmal im Vorraus
Grüße Hendrix :)

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.11.2016, 17:24:53 via Website

Hallo Hendrix,
was ist das für ein Bitmap dass du da aus den Ressource lädst?
Welche Bildgröße und Filegröße hat es?
Kannst du das nicht direkt auf dem Canvas über die DrawMethoden zeichnen?

Ansonsten: Die Speicherverwaltung ist in Android etwas gewöhnungsbedürftig, da blick ich auch nicht immer durch.

ABER: Du erstellt alle 5 sekunden ein neues TrapView, das ist höchst Ineffektiv.
Warum sagst du nicht einfach dem Canvas auf der vorhandenen Traps view dass dieses was anderes Zeigen soll?
Dann musst du auch nur einmal das Bild laden und nur noch die Größe immer entsprechend anpassen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Hendrix

Antworten
Hendrix
  • Forum-Beiträge: 22

24.11.2016, 17:47:38 via Website

Erstmal danke pascal für die Antwort :)
11 kb ca
1200 x 200 größe ^^

ist canvas.DrawBitmap keine DrawMthode oder die Falsche?

Die vorherigen TrapViews würden dann aber verschwinden oder? Das will ich nicht die solln erst weg wenn sie den Bildschirm verlassen oder wie meinst du des ?

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.11.2016, 18:39:13 via Website

Naja was ist auf dem Bitmap drauf?
Wenn du eine Historie haben willst, dann speicherst du nicht die Views sondern die Berechnungsdaten.
Daraus kannst du dann bei bedarf den vorherigen Bildzustand wiederherstellen ohne dass unötig Ressourcen benutzt werden müssen.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Hendrix
  • Forum-Beiträge: 22

24.11.2016, 18:46:44 via Website

nicht viel hab auch mal ne andere Größe probiert machts nicht besser iwie^^

oke des is dann doch bisschen zu hoch für mich :/ kp wie ich des anstelln soll

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

24.11.2016, 19:58:17 via Website

Naja so schwer ist das doch nicht oder?
du verwendest deien View einfach wieder, hier mal ein Denkanstoß:
Pseudocode der View;

Canvas myCanvas;
protected void onDraw(Canvas c)
{
//dein zeichehn ausführen und orginalbitmap in variable speichern
myCanvas=c;
//evtl berechnungsparameter speichern
}

public void redrawBitmap()
{
if(myCanvas!=null)
{
myCanvas.Clear();
onDraw(myCanvas); //Neu zeichen
}


public void historyGoBack()
{
//letzes Bild neu zeichen mit den zuletz benutzen Parametern und dem Orginalbild
}

}

LG Pascal //It's not a bug, it's a feature. :) ;)

Hendrix

Antworten
Hendrix
  • Forum-Beiträge: 22

24.11.2016, 20:13:39 via Website

danke dafür pascal werds einbauen und hoffen das es klappt :)

Antworten