Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/202.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android位图重用_Java_Android_Bitmap_Garbage Collection_Reusability - Fatal编程技术网

Java Android位图重用

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(

我是Android的新手! 我在开发一个使用巨大位图(>1200*1000)的应用程序时,Android的SDK遇到了一些大问题,问题是在应用程序开发过程中,我需要多个相同大小的图层/位图(3-5个)。问题是内存堆在这些分配中的一个分配上消耗得非常快,并且会触发OutOfMemory异常

好的方面是我不需要同时使用所有位图

我尝试了recycle()方法调用,尽管我知道它已经过时了,因为位图的内存现在位于堆上,而不是本机内存上。 我还尝试从特定位图中删除所有引用,甚至手动调用System.gc(),但没有用,无法删除位图。 好吧,也许会有我不知道的内存泄漏,尽管我对此表示怀疑

我尝试了各种各样的解决办法,但都不管用

对我来说,最好的选择是重用位图,但是BitmapFactory的解码方法只知道分配一个消耗内存的新位图

我的问题是,你知道一种重用位图像素(覆盖位图的像素而不分配另一个位图/像素数组)的方法吗,这种方法可以与Android一起使用???问题是我不能停留在垃圾收集器解决方案上,因为我的应用程序中有特定的时刻,我必须确保这些位图从内存中删除/其他位图不会被分配

另一个解决方案是:您知道一种直接在SD卡上绘制一些位图的方法,而不需要通过堆内存吗?当我试图分配一个大位图(原始大小的两倍)来连接另外两个处理过的位图时,它会崩溃。。。这就是我问的原因。是否可以直接从数据流实例化画布或其他绘图对象


另一个解决方案是使用虚拟交换内存之类的东西,它将模拟堆内存,但在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我遇到过类似的问题,比如where
recycle()
对我不起作用。因此,我做了一些琐碎的事情,设置了
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,但我已经做了,但还不够…仍然摆脱我莫瑞例外。我需要一些能让我重用像素缓冲区或其他东西的东西。