我的应用使用网络上的图片来设置壁纸。但是,当我尝试使用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异常?所有帮助表示赞赏。
答案 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);
瞧瞧!
(假设壁纸管理器正确处理超大图像,但很可能就是这种情况)