2011-06-19 7 views
3

J'ai une application dans laquelle je lis des données GPS et je les affiche sur la carte et j'ajoute également une superposition à cette position qui est une petite image .png. Je lis les données dans un thread Async Task et dans la méthode onProgressUpdate je mets à jour mon GUI en ajoutant la superposition à une nouvelle position. Voici mon code:Android La taille du bitmap OutOfMemoryError dépasse le budget VM

 Drawable marker;   
public void onCreate(Bundle savedInstanceState) { 
      marker=getResources().getDrawable(R.drawable.curent_loc); 
    marker.setBounds(0, 0, marker.getIntrinsicWidth(), 
      marker.getIntrinsicHeight()); 

    } 

Ici je lis les données GPS:

public class InitTask extends AsyncTask<Void, GeoPoint, Void> { 
protected Void doInBackground(Void... voids) { 

     p = new GeoPoint(latitude, longitude); 
        publishProgress(p); 
        Thread.sleep(1500); 
       } 

/*in here I update my GUI*/ 
    protected void onProgressUpdate(GeoPoint... progress1) { 
    mapView.getOverlays().add(new SitesOverlay(marker,progress1[0])); 
       theRouteDraw(progress1[0]); 
       } 
     } 

Alors je lis un nouvel emplacement et ajouter une superposition à cette position. Pour cela j'utilise ma classe SitesOverlay qui s'étend Overlay.

Tout se passe bien jusqu'à ce que, à un moment où je reçois l'exception suivante:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method) 
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:392) 
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:405) 
at com.google.android.maps.StreetViewRenderer.getOverlay(StreetViewRenderer.java:149) 
com.google.android.maps.StreetViewRenderer.renderTile(StreetViewRendere 
at com.google.android.maps.AndroidTileOverlayRenderer.renderTile(AndroidTileOverlayRenderer.java:62) 
at com.google.googlenav.map.Map.drawTile(Unknown Source) 
at com.google.googlenav.map.Map.drawMapBackground(Unknown Source) 
at com.google.googlenav.map.Map.drawMap(Unknown Source) 
at com.google.android.maps.MapView.drawMap(MapView.java:1029) 
at com.google.android.maps.MapView.onDraw(MapView.java:468) 
at android.view.View.draw(View.java:6535) 
at android.view.ViewGroup.drawChild(ViewGroup.java:1531) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258) 
at android.view.ViewGroup.drawChild(ViewGroup.java:1529) 

J'ai essayé de recycle mon drawable mais je reçois cette erreur, et après un certain temps, je trouve ceci:

//decodes image and scales it to reduce memory consumption 
private Bitmap decodeFile(File f){ 
    try { 
     //Decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(new FileInputStream(f),null,o); 

     //The new size we want to scale to 
     final int REQUIRED_SIZE=70; 

     //Find the correct scale value. It should be the power of 2. 
     int width_tmp=o.outWidth, height_tmp=o.outHeight; 
     int scale=1; 
     while(true){ 
      if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
       break; 
      width_tmp/=2; 
      height_tmp/=2; 
      scale*=2; 
     } 

     //Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
    } catch (FileNotFoundException e) {} 
    return null; 
} 

Je trouve que ici: Strange out of memory issue while loading an image to a Bitmap object

Mais j'ai quelques problèmes dans la compréhension i t:

* Pourquoi utiliser un File f en tant que paramètre? Est-ce le dessinable que je veux utiliser? Est-ce que ceci doit être fait chaque fois que j'utilise ce dessinable ou seulement dans onCreate()?

Donc, si quelqu'un pouvait expliquer comment utiliser cela, je serais plus que reconnaissant, ou si vous avez une solution de travail plus simple, ce serait encore mieux.

Répondre

2

Cela a été un énorme problème avec Android depuis des lustres. La classe Bitmap, la fonction getDrawable, etc repose sur le bitmap.h sous-jacent qui est disponible dans le cadre du NDK. Chaque fois qu'un getDrawable renvoie un bitmap, pour une raison quelconque, Android ne libère pas correctement la mémoire lorsque nous n'en avons plus besoin. Une solution de contournement Je l'ai utilisée pour créer une seule instance statique de l'image bitmap quelque part et la référence faible chaque fois que vous en avez besoin. De cette façon au moins une instance de l'image bitmap est chargée dans la mémoire.

Espérons que cela aide.

+1

Pourriez-vous me montrer un peu de votre code pour voir comment vous avez fait cela? Parce que je suis nouveau à la programmation et ce n'est pas très facile pour moi de le faire.Merci :) – adrian

+0

Vous voudrez peut-être vérifier cela - http://stackoverflow.com/questions/4197794/android-custom-view-bitmap-memory-leak :) –

Questions connexes