3

ビットマップを取得し、オリジナルから新しいビットマップを作成してから、新しいビットマップを に設定してImageViewいます。オリジナルをリサイクルすると、そのエラーが発生しますが、オリジナルを描画していませんか? 詳細については、私のコードのコメントをお読みください。ご覧のとおり、描画していないビットマップをリサイクルして、描画するタイルと呼ばれる新しいビットマップを常に作成します。

私のコード:

public void tileImage(Bitmap bm){
    if(bm==null){
        Debug.out("Bitmap is null");
    }
    else{
         Bitmap tile;
         float tileWidth = bm.getWidth();
         float tileHeight =1024;
 //if my bitmap is too wide
         if(bm.getWidth()>width){
             Debug.out("Bitmap too wide: "+bm.getWidth());
 //if this code runs I get no error, if not I get the error
             bm =  Bitmap.createScaledBitmap(bm,
                (int)width,
                (int)(bm.getHeight()*(float)(width/tileWidth)),
                false
                );
           }
         Debug.out("Bitmap height: "+bm.getHeight()+" adjusted width "+bm.getWidth());
 //if my bitmap is too tall
         if(bm.getHeight()>tileHeight){
              for(int i = 0; tileHeight*i<bm.getHeight(); i++){
                   image = new ImageView(main);
 //make tiles of the body
                    if((tileHeight*(i+1))<bm.getHeight()){
                         tile = Bitmap.createBitmap(
                                bm,
                                0, 
                                (int)(tileHeight*i),
                                (int)bm.getWidth(),
                                (int)(tileHeight)
                           );
                           Debug.out("Tiling: "+i);
                       }
 //tile the reaminder
                     else{
                           tile = Bitmap.createBitmap(
                               bm,
                               0, 
                               (int)(tileHeight*i),
                               (int)bm.getWidth(),
                               (int)(bm.getHeight()%tileHeight)
                          );
                           Debug.out("Tiling: "+bm.getHeight()%tileHeight+" "+i);
                     }  
                image.setImageBitmap(tile);
                tiles.addView(image);               
           }
         }
 //else its not too tall
    else{
        image = new ImageView(main);

        Debug.out("No tiling");

        tile = Bitmap.createBitmap(
                 bm,
                 0, 
                 0,
                 (int)bm.getWidth(),
                 (int)bm.getHeight()
                 );
        Debug.out("Bitmap too small height: "+bm.getHeight()+" width "+bm.getWidth());
            image.setImageBitmap(tile);
        tiles.addView(image); 

    }

  }
 //this is the trouble maker
bm.recycle();
}
4

2 に答える 2

0

上記の答えは完全に正しいわけではありません。実際、recycle で onDestroy まで待つべきではありません。特に、これらのビットマップの作成を多用する場合。OOM エラーが発生する前に、onDestroy に到達することさえできない場合があります。あなたがすべきことは、ビットマップの寸法にスケーリングする寸法をテストすることです。それらが等しい場合は、元のビットマップを返します。リサイクルは必要ありません。それ以外の場合は、新しいビットマップ オブジェクトを取得するので、元のビットマップに対してすぐに recyle を呼び出す必要があります。

http://developer.android.com/training/displaying-bitmaps/manage-memory.htmlを参照してください

于 2014-01-09T09:54:05.523 に答える