Android - 每个主屏幕都有不同的位图壁纸 - OutOfMemory
我尝试为每个主屏幕设置不同的壁纸,但出现内存不足问题。我有 5 个位图,我试图将它们叠加在壁纸位图上,该位图是显示宽度的 5 倍。使用下面的代码我得到 OOM。问题似乎是创建大壁纸位图的第一行代码。我的问题是是否有办法做到这一点(即占用更少内存的某种方式,或者分配更多内存的某种方式??)。谢谢!
Bitmap wallpaper = Bitmap.createBitmap(displayWidth*5,displayHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(wallpaper);
Uri data = getIntent().getData();
Bitmap bmp = getBitmap(data, imagePosition, displayWidth, displayHeight);
canvas.drawBitmap(bmp, 0, 0,null);
WallpaperManager wallpaperManager = (WallpaperManager) SetterActivity.this.getSystemService(Context.WALLPAPER_SERVICE);
wallpaperManager.setBitmap(wallpaper);
wallpaperManager.suggestDesiredDimensions(bmp.getWidth()*2, bmp.getHeight());
I am trying to set a different wallpaper for every home screen, but I get OutOfMemory issues. I have 5 Bitmaps which I am trying to overlay on a wallpaper Bitmap which is 5 times the display width. Using the code below I get OOM. The problem seems to be the first line of code which creates the large wallpaper Bitmap. My question is whether there is a way to do this (i.e. some way that takes up less memory, or someway to allocate more memory??). Thanks!
Bitmap wallpaper = Bitmap.createBitmap(displayWidth*5,displayHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(wallpaper);
Uri data = getIntent().getData();
Bitmap bmp = getBitmap(data, imagePosition, displayWidth, displayHeight);
canvas.drawBitmap(bmp, 0, 0,null);
WallpaperManager wallpaperManager = (WallpaperManager) SetterActivity.this.getSystemService(Context.WALLPAPER_SERVICE);
wallpaperManager.setBitmap(wallpaper);
wallpaperManager.suggestDesiredDimensions(bmp.getWidth()*2, bmp.getHeight());
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您无法避免一次加载 5 个屏幕的图像,您可以尝试一次只加载一个,并根据当前正在查看的主屏幕进行切换。
也就是说,内存中有 2 个位图,一个是
当前
,一个是下一个
。在第一个视图上加载当前
位图。使用onOffsetsChanged
确定何时发生滚动,然后根据接下来要显示的主屏幕加载位图next
。您需要自己进行从屏幕 A 到屏幕 B 的插值。滚动完成后,回收current
并将next
保存为current
。我确信这个实现中存在一些我现在没有想到的问题,但是使用此方法您只会分配 2 个位图。祝你好运!
If you can't get around having 5 screens worth of images loaded at a time, you could try only having one loaded at a time, and switch based on which home screen is currently being viewed.
That is, you have 2 bitmaps in memory, one is
current
and one isnext
. Load thecurrent
bitmap on first view. UseonOffsetsChanged
to determine when a scroll is happening, and at that point load bitmapnext
based on which home screen will be showing next. You'll need to do that interpolation from screen A to B on your own. when the scroll is finished, recyclecurrent
and savenext
ascurrent
.I'm sure there are some gotchas in this implementation that I'm not thinking of right now, but you'll only ever have 2 bitmaps allocated with this method. Good luck!
位图数据在本机堆中分配(有关详细信息,请参阅 BitmapFactory OOM 让我发疯) )。可用的数量取决于平台(例如,API 级别 2.2 的本机堆总数为 24M),但没有办法将其增长到超出这个范围。分配多少本机堆空间取决于您和其他应用程序对位图/图形的处理。
您的第一行代码/壁纸位图只有 480 * 800 * 32 / 8 = 1.536 MB,这完全在最大值之内。那么,当您到达该行时,大部分堆似乎已经分配了?
请注意,本机堆会进行垃圾收集,但很少进行 - 如果应用程序未显式释放数据,则不会恢复数据。因此,如果您在运行应用程序时没有回收位图(在 onDestroy 中),您可能会在几次运行后耗尽本机堆。
Bitmap data is allocated in the Native heap (see BitmapFactory OOM driving me nuts for details). How much is available depends on the platform (eg API level 2.2 has 24M Native heap total), but there is no way to grow it beyond that. And how much of the native heap space is allocated depends on what your and other applications are doing with bitmaps/graphics.
Your first line of code / wallpaper bitmap is only 480 * 800 * 32 / 8 = 1.536 Mbytes, which is well within the maximum. So it appears likely that much of the heap is already allocated by the time you get to that line?
Note that the native heap is garbage collected but infrequently - and data is not recovered if the application does not explicitly free it. So if you were running application without recycling your bitmaps (in onDestroy) you might well eat up the Native heap after a few runs.