【问题标题】:Dealing with Large Bitmaps (tiling a small bitmap to create wallpaper)处理大位图(平铺小位图以创建壁纸)
【发布时间】:2011-04-30 16:29:54
【问题描述】:

我遇到了内存问题,我认为这可能与创建大型位图有关。

手头的任务是获取一个相当小的平铺图像并创建一个更大的平铺图像并将其设置为手机壁纸。我这样做的方式是:

1) 创建一个 2 * 屏幕宽度,1 * 屏幕高度的视图

2) 将视图背景设置为 BitmapDrawable,平铺模式设置为重复

3) 创建具有视图尺寸的位图

4) 将视图绘制到位图上:view.draw(new Canvas(bitmap))

5) 设置壁纸:getApplicationContext().setWallpaper(bitmap)

这在我的手机 (HTC Magic) 和我尝试过的其他手机上运行良好。但是我收到了与此问题相关的错误报告。我试图通过将所需尺寸加倍来重新创建问题,当视图被绘制到位图时,问题似乎发生在第四步:

ERROR/dalvikvm-heap(124):需要堆按摩(7372800 字节外部分配太大)

我不确定如何解决这个问题。请帮忙! 谢谢

【问题讨论】:

  • 自 Android 4.0 以来,提供了更好的调试可能性,因为用于位图分配的内存现在被正确列为 DDMS 中堆监视器中使用的内存。在 4.0 之前,用于位图分配的内存没有显示在堆监视器中,因此只能猜测实际使用了多少内存。也许这可以帮助您更好地调试代码。

标签: android memory views bitmap


【解决方案1】:

实际上你可以重构你的代码。如果您不使用View,您将获得更好的性能并且可能使用更少的内存

  1. 创建所需大小的Bitmap bitmap = Bitmap.createBitmap(width,height,Bitamp.Config.RGV_565)(或ARGB_8888,这也可能有效)
  2. 创建一个canvas = new Canvas(bitmap)
  3. 自己创建平铺图像,来自您的src

简化代码:

// set another matrix if you want rotation/scaling of the input
Matrix identity=new Matrix(); 
for (int i=0; i<maxLines; i++) {
  for (int j=0; j<maxCol; j++) {
    canvas.draw(src, identity,anyPaint);
  }
}

保留完结壁纸getApplicationContext().setWallpaper(bitmap)

【讨论】:

  • 谢谢刚刚尝试过,似乎是个好主意。很难看出它有多大的不同(怀疑它会对内存产生多大影响),因为这个问题一开始在我的手机上并没有发生太多。无论如何,谢谢!
  • 在你的代码中,像 identity.setTranslate(patternWidth * i,patternHeight * j) 这样的东西必须在每次绘制调用之前添加。
【解决方案2】:

不幸的是,我认为您无能为力...我们在这里使用手机; Android 将进程内存限制为 16MB。

以下是我可以给您的一些提示和技巧(因为我的应用程序中存在相同的问题)

  • 您确定需要 32 位像素吗?那是三个 8 位颜色通道和一个 8 位 Alpha 通道。您可以使用 RGB_565 以获得视觉上可接受的结果。

  • 回收创建位图时不需要的图像(并且不需要绘制位图)

  • null 任何其他您不需要的对象

  • 在创建 Bitmap 之前运行 System.gc() 以强制进行垃圾回收

希望这会有所帮助!

【讨论】:

  • 还有一个不好的提示:不要使用大于所需的图像:-)
  • 谢谢,但已经尝试了所有这些,但仍然不时收到用户报告的问题......也许你是对的,这可能只是移动设备的限制,只需要优化一切使用位图的地方。
【解决方案3】:

不确定这是否是您的解决方案,但您看过了吗? BitmapFactory.Options.inTempStorage

你的使用方式是:


BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
Bitmap bitmap_origin = BitmapFactory.decodeFile(path, options);

【讨论】:

    【解决方案4】:

    我确定您已经想到了,但是:您是否包括在内

    <uses-permission android:name="android.permission.SET_WALLPAPER" />
    

    在您的清单文件中?

    你确定没有抛出异常?显示 Toast 可能有问题。

    【讨论】:

    • 是的,我有,它适用于我的手机和我尝试过的其他各种手机。为了复制错误,我所做的是使图像更大,实际上尝试为位图分配过多内存是一个问题。我将更改问题以反映这一点。
    猜你喜欢
    • 1970-01-01
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多