java.lang.OutOfMemoryError: bitmap size exceeds VM budget

  • Antworten:1
Nils
  • Forum-Beiträge: 8

07.02.2012, 16:36:19 via Website

Hallo zusammen,

Ich bin dabei ein Spiel zu schreiben, bei dem als hintergrund eine ziemlich große Grafik angezeigt wird (ein jpeg mit 2,14mb). Bisher hatte ich folgenden code:

1private Graphic _map=null;
2 private ArrayList<Town> _towns = new ArrayList<Town>();
3
4 public Panel(Context context) {
5 super(context);
6 getHolder().addCallback(this);
7 preLoad();
8 _thread = new TravelThread(getHolder(), this);
9 setFocusable(true);
10//...
11 private void preLoad(){
12
13 _map=new Graphic(BitmapFactory.decodeResource(getResources(),
14 R.drawable.map));
15 _map.getCoordinates().setX(0);
16 _map.getCoordinates().setY(0);
17
18 _towns = Tb.createTowns(BitmapFactory.decodeResource(getResources(),
19 R.drawable.town));
20 }
21
22 }

Wenn die App gestartet wird wird ein Panel initialisiert und die Grafiken geladen. Einmal die große Grafik _map. und eine kleine Grafik für _towns. _towns ist eine Array-List, der in einer anderen Klasse verschiedene Städte mit Namen und Koordinaten sowie der bitmap "R.drawable.town hinzugefügt werden. Die kleine grafik für die towns ist jedoch nur 4kb groß, also weniger relevant für mein problem.

Wenn man nun die App startet, läuft alles wie es soll und wird auch so dann gezeichnet. Wenn ich jedoch die App schließe und erneut starte, wird der Fehler "java.lang.OutOfMemoryError: bitmap size exceeds VM budget" ausgegeben. Dieser entsteht an der Stelle , wo ich die große Grafik lade.

Nun habe ich mich mit dem Fehler mal im Internet auf Suche begeben. Jedoch nicht viel von dem verstanden, was ich gelesen habe. Öfters mal kam irgendetwas mit statischer Programmierung. Also habe ich das Feld für den Hintergrund(_map) als static deklariert. Dies hat jedoch nicht geändert.

Ich hab dann weiter drüber nachgedacht, wie ich dieses Problem lösen kann und hab die preLoad() Methode wie folgt geändert und das Feld für _map weiterhin statisch gelassen:

1private void preLoad(){
2 if(_map==null){
3 _map=new Graphic(BitmapFactory.decodeResource(getResources(),
4 R.drawable.map));
5 }
6 _map.getCoordinates().setX(0);
7 _map.getCoordinates().setY(0);
8
9
10 _towns = Tb.createTowns(BitmapFactory.decodeResource(getResources(),
11 R.drawable.town));
12 }

Nun kann ich die App öffnen und wieder schließen und es kommt keine Error.
Ich verstehe allerdings nicht genau warum es jetzt funktioniert, da _map ja bei jedem Start eigentlich gleich null gesetzt wird und sich somit eigentlich nichts geändert hat.
Kann mir vielleicht jemand weiter helfen und/oder mir eine bessere Variante zur Lösung dieses Problem geben, da ich noch ein paar weitere Grafiken einbinden muss für das Spiel.

Ein anderer Lösungsansatz, an welchen ich dachte ist VM budget manuell freizugeben. Ich habe jedoch keinen dazu passenden Befehl gefunden und bin mir nicht sicher, ob es überhaupt möglich ist. Vieleicht wüsst ihr ja etwas dazu.

Gruß,
Nils

PS: Ich habe das ganze auf meinem Galaxy S2 getestet und über Eclipse gestartet.

Antworten