OutOfMemory解码位图时的异常

时间:2014-08-06 16:59:07

标签: java android out-of-memory

我的应用使用网络上的图片来设置壁纸。但是,当我尝试使用BitmapFactory decodeStream时,较慢的手机上的某些用户会获得OutOfMemory异常。此图像永远不会显示在应用程序上,只是加载,然后设置为壁纸。我在网上搜索过,但我一直找不到任何有助于解决问题的资源。

代码:

public void setWallpaperMethod(){

    InputStream in = null;
    try {
        in = new java.net.URL(urldisplay).openStream();
    } catch (MalformedURLException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    final Bitmap bitmap = BitmapFactory.decodeStream(in);
    myWallpaperManager = WallpaperManager
            .getInstance(getApplicationContext());

    runOnUiThread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                myWallpaperManager.setBitmap(bitmap);
                Toast.makeText(MainActivity.this,
                        "Teamwork! Wallpaper set.", Toast.LENGTH_LONG)
                        .show();
            } catch (IOException e) {
                Toast.makeText(
                        MainActivity.this,
                        "Damnit, clickers! Wallpaper wasn't set. Try killing and restarting the app?",
                        Toast.LENGTH_LONG).show();
            }
        }

    });

}

变量urldisplay是一个字符串,等于一个URL(例如,一个imgur图像)。此外,该方法在一个线程中运行,因此不存在UI线程锁定的风险。

那么有谁知道如何解决这个OutOfMemory异常?所有帮助表示赞赏。

2 个答案:

答案 0 :(得分:0)

看看这个链接..

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Android文档建议您对图像进行缩减采样..使用此方法计算样本大小:

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}
那么你会做这样的事情:

// First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);

答案 1 :(得分:0)

目前,您正在打开输入流,读取它,解码完整的fledge位图,然后将其传递给管理器,管理器将其转换为png并存储以供以后使用。

相反,您可以打开输入流,将其传递给经理,现在负责将其存储起来供以后使用。

如您所见,这是一次解码,一次编码较少。

然后,壁纸管理员将负责显示图像,相应地处理图像尺寸。

myWallpaperManager = WallpaperManager
        .getInstance(getApplicationContext());
myWallpaperManager.setStream(in);
瞧瞧!

(假设壁纸管理器正确处理超大图像,但很可能就是这种情况)