android - 为什么我得到 "Cannot draw recycled bitmaps"?

标签 android bitmap

我正在获取位图,从原始位图创建一个新位图,然后将新位图设置为 ImageView,当我回收原始位图时出现该错误,但我没有绘制原始位图?有关更多详细信息,请阅读我在代码中的评论。如您所见,我回收了我未绘制的位图,我总是制作一个名为 tile 的新位图来绘制。

我的代码:

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

最佳答案

  • Bitmap.createBitmap(params) 从源位图的指定子集中返回一个不可变位图。新位图可能是与源相同的对象,或者可能已经制作了副本。

  • bitmap.recycle() 方法释放与此位图关联的 native 对象,并清除对像素数据的引用。这是一个高级调用,通常不需要调用,因为当不再有对该位图的引用时,正常的 GC 进程将释放该内存。

  • onDraw() 方法需要一些时间来膨胀 View 。如果您传递位图来绘制 View 并在同一引用上调用 recycle(),则该位图将被标记为“已死”,这意味着如果调用 getPixels() 或 setPixels() 它将抛出异常,并且不会绘制任何内容.

  • 您应该在 onDestroy() 中调用 recycle()。

我的代码:

public class MainActivity extends Activity {
    private Bitmap mBitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView image1 = (ImageView) findViewById(R.id.image1);
        mBitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.ic_launcher);
        image1.setImageBitmap(mBitmap);
        tileImage();
    }

    private void tileImage() {
        ImageView image2 = (ImageView) findViewById(R.id.image2);
        Bitmap bm = Bitmap.createBitmap(mBitmap, 0, 0,
            (int) mBitmap.getWidth(), (int) mBitmap.getHeight());
        image2.setImageBitmap(bm);
    }

    @Override
    protected void onDestroy() {
        mBitmap.recycle();
        super.onDestroy();
    }
}

关于android - 为什么我得到 "Cannot draw recycled bitmaps"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726934/

相关文章:

java - Android 自定义事件监听器

javascript - 为什么我使用位图缓冲区在索引和 x,y 之间转换的算法会导致图像垂直翻转?

android - 如何在 Android 上的 Glide 中显示数据库图像?

android - 如何在 Android 中完全加载 ImageView 时获取

c# - "Parameter is not valid."使用保存位图时

Android 层列表 : bitmap issue with app:srcCompat

c# - Xamarin Android 上的 NLog 日志文件存储在哪里?

Android Webview 下载管理器下载 PDF 文件

java - 如何分别为多个 ​​ListView 实现 onItemClick()?

android - 如何用 Gradle 3.0 替换 apt()