Java Android位图重用
我是Android的新手! 我在开发一个使用巨大位图(>1200*1000)的应用程序时,Android的SDK遇到了一些大问题,问题是在应用程序开发过程中,我需要多个相同大小的图层/位图(3-5个)。问题是内存堆在这些分配中的一个分配上消耗得非常快,并且会触发OutOfMemory异常 好的方面是我不需要同时使用所有位图 我尝试了recycle()方法调用,尽管我知道它已经过时了,因为位图的内存现在位于堆上,而不是本机内存上。 我还尝试从特定位图中删除所有引用,甚至手动调用System.gc(),但没有用,无法删除位图。 好吧,也许会有我不知道的内存泄漏,尽管我对此表示怀疑 我尝试了各种各样的解决办法,但都不管用 对我来说,最好的选择是重用位图,但是BitmapFactory的解码方法只知道分配一个消耗内存的新位图 我的问题是,你知道一种重用位图像素(覆盖位图的像素而不分配另一个位图/像素数组)的方法吗,这种方法可以与Android一起使用???问题是我不能停留在垃圾收集器解决方案上,因为我的应用程序中有特定的时刻,我必须确保这些位图从内存中删除/其他位图不会被分配 另一个解决方案是:您知道一种直接在SD卡上绘制一些位图的方法,而不需要通过堆内存吗?当我试图分配一个大位图(原始大小的两倍)来连接另外两个处理过的位图时,它会崩溃。。。这就是我问的原因。是否可以直接从数据流实例化画布或其他绘图对象Java Android位图重用,java,android,bitmap,garbage-collection,reusability,Java,Android,Bitmap,Garbage Collection,Reusability,我是Android的新手! 我在开发一个使用巨大位图(>1200*1000)的应用程序时,Android的SDK遇到了一些大问题,问题是在应用程序开发过程中,我需要多个相同大小的图层/位图(3-5个)。问题是内存堆在这些分配中的一个分配上消耗得非常快,并且会触发OutOfMemory异常 好的方面是我不需要同时使用所有位图 我尝试了recycle()方法调用,尽管我知道它已经过时了,因为位图的内存现在位于堆上,而不是本机内存上。 我还尝试从特定位图中删除所有引用,甚至手动调用System.gc(
另一个解决方案是使用虚拟交换内存之类的东西,它将模拟堆内存,但在SD卡或其他东西上进行缓存。但是也找不到执行此操作的方法。编写一个单独的类来执行自定义位图操作:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
class BitmapLoader
{
public static int getScale(int originalWidth,int originalHeight,
final int requiredWidth,final int requiredHeight)
{
//a scale of 1 means the original dimensions
//of the image are maintained
int scale=1;
//calculate scale only if the height or width of
//the image exceeds the required value.
if((originalWidth>requiredWidth) || (originalHeight>requiredHeight))
{
//calculate scale with respect to
//the smaller dimension
if(originalWidth<originalHeight)
scale=Math.round((float)originalWidth/requiredWidth);
else
scale=Math.round((float)originalHeight/requiredHeight);
}
return scale;
}
public static BitmapFactory.Options getOptions(String filePath,
int requiredWidth,int requiredHeight)
{
BitmapFactory.Options options=new BitmapFactory.Options();
//setting inJustDecodeBounds to true
//ensures that we are able to measure
//the dimensions of the image,without
//actually allocating it memory
options.inJustDecodeBounds=true;
//decode the file for measurement
BitmapFactory.decodeFile(filePath,options);
//obtain the inSampleSize for loading a
//scaled down version of the image.
//options.outWidth and options.outHeight
//are the measured dimensions of the
//original image
options.inSampleSize=getScale(options.outWidth,
options.outHeight, requiredWidth, requiredHeight);
//set inJustDecodeBounds to false again
//so that we can now actually allocate the
//bitmap some memory
options.inJustDecodeBounds=false;
return options;
}
public static Bitmap loadBitmap(String filePath,
int requiredWidth,int requiredHeight){
BitmapFactory.Options options= getOptions(filePath,
requiredWidth, requiredHeight);
return BitmapFactory.decodeFile(filePath,options);
}
}
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
类位图加载器
{
公共静态int getScale(int原始宽度、int原始高度、,
最终整型要求宽度,最终整型要求高度)
{
//比例为1表示原始尺寸
//保持图像的完整性
int标度=1;
//仅当高度或宽度
//图像超出了要求的值。
如果((原始宽度>所需宽度)| |(原始高度>所需高度))
{
//计算有关
//较小的维度
如果(originalWidth编写一个单独的类来执行自定义位图操作:
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
class BitmapLoader
{
public static int getScale(int originalWidth,int originalHeight,
final int requiredWidth,final int requiredHeight)
{
//a scale of 1 means the original dimensions
//of the image are maintained
int scale=1;
//calculate scale only if the height or width of
//the image exceeds the required value.
if((originalWidth>requiredWidth) || (originalHeight>requiredHeight))
{
//calculate scale with respect to
//the smaller dimension
if(originalWidth<originalHeight)
scale=Math.round((float)originalWidth/requiredWidth);
else
scale=Math.round((float)originalHeight/requiredHeight);
}
return scale;
}
public static BitmapFactory.Options getOptions(String filePath,
int requiredWidth,int requiredHeight)
{
BitmapFactory.Options options=new BitmapFactory.Options();
//setting inJustDecodeBounds to true
//ensures that we are able to measure
//the dimensions of the image,without
//actually allocating it memory
options.inJustDecodeBounds=true;
//decode the file for measurement
BitmapFactory.decodeFile(filePath,options);
//obtain the inSampleSize for loading a
//scaled down version of the image.
//options.outWidth and options.outHeight
//are the measured dimensions of the
//original image
options.inSampleSize=getScale(options.outWidth,
options.outHeight, requiredWidth, requiredHeight);
//set inJustDecodeBounds to false again
//so that we can now actually allocate the
//bitmap some memory
options.inJustDecodeBounds=false;
return options;
}
public static Bitmap loadBitmap(String filePath,
int requiredWidth,int requiredHeight){
BitmapFactory.Options options= getOptions(filePath,
requiredWidth, requiredHeight);
return BitmapFactory.decodeFile(filePath,options);
}
}
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
类位图加载器
{
公共静态int getScale(int原始宽度、int原始高度、,
最终整型要求宽度,最终整型要求高度)
{
//比例为1表示原始尺寸
//保持图像的完整性
int标度=1;
//仅当高度或宽度
//图像超出了要求的值。
如果((原始宽度>所需宽度)| |(原始高度>所需高度))
{
//计算有关
//较小的维度
if(originalWidth我遇到过类似的问题,比如whererecycle()
对我不起作用。因此,我做了一些琐碎的事情,设置了myBitmap=null
。这向垃圾收集器表明myBitmap已被取消引用,不再需要它。因此,它将完成释放堆的工作。然后,您可以继续使用myBitmap加载新位图,而不会出现内存异常。我已经有了su在recycle()中也有类似的问题
对我不起作用。所以我做了一些琐碎的事情,比如设置myBitmap=null
。这向垃圾收集器表明myBitmap已被取消引用,不再需要它。因此它将完成释放堆的工作。然后,您可以继续使用myBitmap加载新位图,而不会出现内存异常。这可能是错误的太晚了,但我建议使用“BitmapFactory.Options.inBitmap”。如果设置,skia将尝试重新使用此位图解码图像。
这可能太晚了,但我建议使用“BitmapFactory.Options.inBitmap”。如果设置,skia将尝试重新使用此位图解码图像。
“我尝试了recycle()方法调用,尽管我知道它已经过时了,因为位图的内存现在位于堆上,而不是本机内存上。”。这是一种真实情况,因为Android 3.2是的!我的目标是Android 4.0!”我尝试了recycle()方法调用,尽管我知道它已经过时,因为位图的内存现在位于堆上,而不是本机内存上。”.这是真的,因为Android 3.2是的!我在Android 4.0中的目标!比你,vickey,但我已经做了,但这还不够…仍然摆脱内存异常。我需要一些可以让我重用像素缓冲区或其他东西的东西。比你,vickey,但我已经做了,但还不够…仍然摆脱我莫瑞例外。我需要一些能让我重用像素缓冲区或其他东西的东西。