2011-09-14 9 views
3

マップアプリケーションがあります。私のコードのどこかで、データベースからキャンバスにデータをレンダリングしています。 「メモリ不足」の例外が発生しましたが、回避する方法はわかりません。ループ内にビットマップを作成するときにメモリリークが発生する

これは関連する方法です。 bitmapfactoryでビットマップを作成するときに例外が発生します。

private static void _renderImage(Canvas g, Point[] points, RImageData imageData, 
           RMapView mapView) { 

    Bitmap image = (Bitmap)imageData.image; 
    Paint paint = new Paint(); 
    if(image == null) { 
     image = BitmapFactory.decodeByteArray(imageData.getImageBytes(), 0, 
               imageData.getImageBytes().length); 
     imageData.image = image; 
    } 
    g.drawBitmap(image, points[0].x, points[0].y, paint); 
} 

私はイメージをリサイクルしようとしましたが、キャンバスはリサイクルビットマップで動作しません。

どのような解決策も非常に評価されます。

+0

_renderImage()を頻繁に呼び出していますか? – mcfinnigan

+0

キャンバスに描画されるタイル(イメージの塊)を想像してみてください。 – no9

答えて

2

ビットマップキャッシュを使用することをお勧めします。プリハニカムの画像をリサイクルしてもメモリを解放するには時間がかかります(ビットマップデータはdalvikによって直接管理されていないネイティブメモリに保存されます)。次に、ビットマップキャッシュのサンプルを示します。あなたのニーズに合わせて調整してください。

/** 
* @author audrius Bitmap cache 
*/ 
private static class BitmapCache { 
    //private static final String TAG = "BitmapCache"; 
    private final int mCacheSize; 
    private final String mBitmapLocation; 
    private LinkedHashMap<String, Bitmap> mBitmapCache; 

    /** 
    * Constructor 
    * 
    * @param cacheSize 
    *   Cache size in element count (e.g. 8 = at most 8 Bitmaps in 
    *   cache) 
    * @param bitmapLocation 
    *   Physical root path to bitmap location 
    */ 
    public BitmapCache(int cacheSize, String bitmapLocation) { 
     mCacheSize = cacheSize; 
     mBitmapLocation = bitmapLocation; 

     mBitmapCache = new LinkedHashMap<String, Bitmap>(mCacheSize + 1) { 
      private static final long serialVersionUID = -4156123801558395154L; 

      @Override 
      protected boolean removeEldestEntry(
        java.util.Map.Entry<String, Bitmap> eldest) { 
       return size() > mCacheSize; 
      }; 

      @Override 
      public Bitmap remove(Object key) { 
       Bitmap bmp = super.get(key); 
       // make sure to release resources as soon as possible 
       bmp.recycle(); 
       return super.remove(key); 
      } 
     }; 
    } 

    /** 
    * Returns Bitmap (either from cache or physical location) 
    * 
    * @param bitmapFilename 
    * @return 
    */ 
    public Bitmap getBitmap(String bitmapFilename) { 
     Bitmap ret = mBitmapCache.get(bitmapFilename); 
     //Log.v(TAG, "getBitmap : " + bitmapFilename); 
     if (ret == null) { 
      //Log.v(TAG, "Bitmap not cached, reading location : " + mBitmapLocation); 
      ret = BitmapFactory.decodeFile(new File(mBitmapLocation, bitmapFilename).getAbsolutePath()); 
      mBitmapCache.put(bitmapFilename, ret); 
     } 

     return ret; 
    } 

    /** 
    * Clears bitmap cache 
    */ 
    public void clear() { 
     if (mBitmapCache != null) { 
      for (Bitmap bitmap : mBitmapCache.values()) { 
       if (bitmap != null) bitmap.recycle(); 
      } 

      mBitmapCache.clear(); 
     } 
    } 
} 
1

私はイメージをリサイクルしようとしましたが、キャンバスはリサイクルされたビットマップで動作しません。

私は考えているのは、ビットマップを "リサイクル"し、それをガベージコレクタが処理するために床にドロップすることです。

ここでjavadocはおよそrecycle()言うものです:。

「これは、同期ピクセルデータを解放しません。このビットマップに関連付けられているネイティブオブジェクトを解放し、ピクセルデータへの参照をクリアし、それは単にそれを可能にビットマップは "dead"とマークされ、getPixels()またはsetPixels()が呼び出された場合に例外をスローし、何も描画しません。この操作は元に戻すことはできません。このビットマップへの参照がなくなると、通常のGCプロセスでこのメモリが解放されるため、これは高度な呼び出しであり、通常呼び出す必要はありません。 ap。 "

+0

は意味があります。しかし私がそれを行うことができる唯一の場所はこの方法です。そして、私が "drawBitmap"呼び出しの後でもリサイクルすれば、私はまだキャンバスからエラーが出ています... – no9

関連する問題