我最近创建了动态壁纸。它确实显示两个相邻的图像。每个图像确实占据屏幕宽度的一半。移动屏幕(在主屏幕上移动到两侧)时,图像也会移动。
我希望它看起来尽可能好,所以我所有的背景图像的分辨率都是 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);
它不适合我的屏幕(我必须在计算尺寸时出错)。这是正确的方式吗?修复计算时可能会更快(将裁剪较低的区域)?