2011-06-19 11 views
3

私はいくつかのGPSデータを読み込んで地図上に表示するアプリを持っており、その位置にオーバーレイを追加しました。これは小さい.png画像です。Android OutOfMemoryErrorビットマップサイズがVMの予算を超えています

私はAsync Taskスレッドのデータを読んでいます。onProgressUpdateメソッドでは、新しい位置にオーバーレイを追加してGUIを更新します。 GPSデータを読み込むここで

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

    } 

私は:ここに私のコードがある

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]); 
       } 
     } 

だから私は、新しい場所を読んで、私はその位置でオーバーレイを追加します。そのためには、Overlayを拡張するクラスSitesOverlayを使用します。

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) 

私は私の描画可能にrecycleしようとしたが、それでも私はそのエラーを取得し、しばらく後に、私はこの見つかりました:

//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; 
} 
を私は次の例外を受け取るかの時点でまで

すべてがうまくいきます

は、私はここにいることが見つかりました: Strange out of memory issue while loading an image to a Bitmap object

しかし、私は理解する上でいくつかの問題を抱えている私t:

*まず、File fをパラメータとして使用している理由は何ですか?これは私が使用したいドローイングですか?このドロウアブルを使用するたびに、またはonCreate()でのみこれを行う必要がありますか?

誰かがそれを使用する方法を説明できたら、私は感謝以上のものになります。あるいは、より簡単な解決策があれば、それはさらに優れています。

答えて

2

これは、年齢のAndroidで大きな問題となっています。 Bitmapクラス、getDrawable関数などは、NDKの一部として利用可能な基になるbitmap.hに依存します。 getDrawableがビットマップを返すたびに、何らかの理由でAndroidが必要なくなったときにメモリが適切に解放されません。

回避策1つの回避策ビットマップの静的インスタンスを1つ作成し、必要に応じて弱い参照を作成するために使用しました。この方法では、ビットマップの少なくとも1つのインスタンスがメモリにロードされます。

これが役に立ちます。

+1

私はあなたのコードを少し見せてくれましたか?私はプログラミングが初めてで、これは私にとっては簡単ではないからです。ありがとう:) – adrian

+0

あなたはこれをチェックしたいと思うかもしれません - http://stackoverflow.com/questions/4197794/android-custom-view-bitmap-memory-leak :) –