2010-07-23 31 views
0

我试图为每个主屏幕设置不同的壁纸,但是出现OutOfMemory问题。我有5个位图,我试图叠加在5倍于显示宽度的壁纸位图上。使用下面的代码,我得到了OOM。该问题似乎是创建大型壁纸位图的第一行代码。我的问题是,是否有办法做到这一点(即某种方式占用较少的内存,或者分配更多的内存??)。谢谢!Android - 为每个主屏幕设置不同的位图壁纸 - OutOfMemory

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()); 
+0

你的位图大小是多少? – Sephy 2010-07-23 12:18:45

+0

嗯,我正在测试Nexus One屏幕尺寸为480x800。首先我创建的壁纸位图必须是5倍大(2400x800)。然后,对于每个主屏幕,我将在尺寸480x800的Canvas上绘制另一个位图。 – timothyjc 2010-07-23 12:41:27

+0

displayWidth和displayHeight的值是什么?他们是内在的宽度和高度吗? (myBitmap.getIntrinsicWidth(),myBitmap.getIntrinsicHeight();) – Jorgesys 2010-07-23 18:04:11

回答

0

如果你不能得到各地有5个屏幕的同时加载的图片,你可以尝试每次只加载具有一个,并基于当前正在查看哪个主画面切换。

也就是说,您在内存中有两个位图,一个是current,另一个是next。在第一个视图中加载current位图。使用onOffsetsChanged来确定何时滚动正在发生,并在此时根据下一个将显示哪个主屏幕来加载位图next。你需要从屏幕A到B自己进行插值。当卷轴结束时,请回收current并将next另存为current

我确定在这个实现中有一些问题,我现在没有想到,但是你只能使用这个方法分配2个位图。祝你好运!

0

位图数据在本地堆中分配(有关详细信息,请参阅BitmapFactory OOM driving me nuts)。有多少可用取决于平台(例如,API级别2.2具有24M原生堆总数),但是没有办法将其扩展到超过这个范围。多少本机堆空间分配取决于您的和其他应用程序在位图/图形上所做的工作。

您的第一行代码/壁纸位图仅为480 * 800 * 32/8 = 1.536 Mbytes,这在最大范围内。因此,当你到达那条线时,很可能已经分配了大部分堆?

请注意,本机堆是垃圾收集但很少 - 如果应用程序没有明确释放数据,则数据不会恢复。因此,如果你正在运行应用程序而没有回收你的位图(在onDestroy中),你可能会在几次运行后吃掉Native堆。