我最近创作了动态壁纸。它确实显示彼此相邻的两个图像。每张图片占据屏幕宽度的一半。移动屏幕(移动到主屏幕的两侧)时,图像也会移动。
我希望它看起来尽可能好,所以所有背景图片的分辨率都是1320x958 。我知道高度不合理,但这是我用过的大部分图片中最好的。
在壁纸开始时,图像缩放到屏幕高度并计算适当的宽度。它在具有较小显示器(ldpi,mdpi)的设备上运行良好
问题是具有大屏幕的设备,其中需要升级(而不是缩小)我的图像,突然我得到java.lang.OutOfMemoryError
。我收到了三星S3的崩溃报告,我不明白当具有较小屏幕(和较少内存)的旧设备没有任何问题时,如何在具有大屏幕(具有更多可用内存)的设备上发生这种情况。
这是我的代码:
private void InitializeBackgrounds()
{
Resources res = getApplicationContext().getResources();
// Load and scale backgrounds
int bg_height = height;
int bg_width = (int)((float)bg_height/958.0f*1320.0f);
try {
// Load random image from array of images
Bitmap original = BitmapFactory.decodeResource(res, left_files[r.nextInt(left_files.length)]);
// Scale image to new size
spurs = Bitmap.createScaledBitmap(original, bg_width, bg_height, true);
// Free up memory immediately
original.recycle();
// Do the same for right image
original = BitmapFactory.decodeResource(res, right_files[r.nextInt(right_files.length)]);
heat = Bitmap.createScaledBitmap(original, bg_width, bg_height, true);
original.recycle();
}
catch (OutOfMemoryError e){
throw new OutOfMemoryError("OutOfMemoryException;InitializeBackgrounds(); model: " + Build.MODEL + "; LocalizedMessage: "+e.getLocalizedMessage()+"; Message: "+e.getMessage());
}
}
稍后,在绘制时,会加载加载的图像以适合屏幕的宽度。移动屏幕时会产生移动图像的效果。这就是为什么我在内存中加载了比屏幕大的图像。
private void drawWallpaper(Canvas c)
{
// ...
try {
bg_left = Bitmap.createBitmap(spurs, x_shift, 0, width/2, height);
bg_right = Bitmap.createBitmap(heat, x_shift, 0, width/2, height);
}
catch (OutOfMemoryError e){
throw new OutOfMemoryError("OutOfMemoryException;DrawWallpaper(); model: " + Build.MODEL + "; LocalizedMessage: "+e.getLocalizedMessage()+"; Message: "+e.getMessage());
}
// Draw backgrounds
c.drawBitmap(bg_left, 0, 0, null);
c.drawBitmap(bg_right, width/2, 0, null);
//...
}
你能帮我优化我的代码吗?
更新
我尝试使用变换矩阵绘制位图,但速度很慢。以下是我尝试的方法:
Matrix m = new Matrix();
m.reset();
RectF rect_source = new RectF(x_shift, 0, source_width, original_height);
RectF rect_destination = new RectF(0, 0, width/2, height);
m.setRectToRect(rect_source, rect_destination, Matrix.ScaleToFit.CENTER);
c.drawBitmap(BitmapFactory.decodeResource(res, resource_left), m, null);
它不适合我的屏幕(我必须在计算尺寸方面犯错误)。这是对的吗?修复计算时可能会更快(会缩小区域)吗?