0

我最近创建了动态壁纸。它确实显示两个相邻的图像。每个图像确实占据屏幕宽度的一半。移动屏幕(在主屏幕上移动到两侧)时,图像也会移动。

我希望它看起来尽可能好,所以我所有的背景图像的分辨率都是 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);

它不适合我的屏幕(我必须在计算尺寸时出错)。这是正确的方式吗?修复计算时可能会更快(将裁剪较低的区域)?

4

0 回答 0