Android - 每个主屏幕都有不同的位图壁纸 - OutOfMemory

发布于 2024-09-11 14:26:25 字数 696 浏览 4 评论 0原文

我尝试为每个主屏幕设置不同的壁纸,但出现内存不足问题。我有 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光瘦了 2024-09-18 14:26:25

如果您无法避免一次加载 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 is next. Load the current bitmap on first view. Use onOffsetsChanged to determine when a scroll is happening, and at that point load bitmap next 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, recycle current and save next as current.

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!

肤浅与狂妄 2024-09-18 14:26:25

位图数据在本机堆中分配(有关详细信息,请参阅 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文