gpt4 book ai didi

android - 由于位图大小过大导致内存不足异常

转载 作者:太空宇宙 更新时间:2023-11-03 13:05:35 25 4
gpt4 key购买 nike

由于虚拟内存堆大小有限,我遇到内存不足的问题。
这是我从服务器获取位图的代码:

@SuppressWarnings("unchecked")
public class DrawableManager {

@SuppressWarnings("rawtypes")
private final Map drawableMap;

@SuppressWarnings("rawtypes")
private DrawableManager() {
drawableMap = new HashMap();
}

static private DrawableManager _instance;

static public DrawableManager getInstance() {
if(_instance == null) {
_instance = new DrawableManager();
}
return _instance;
}

public Bitmap fetchBitmap(final String sURL) {
if(sURL.length() == 0)
return null;
Bitmap bm = (Bitmap) drawableMap.get(sURL);
if(bm != null) {
return bm;
}

byte[] imageData = ThumbImg(sURL);

if(imageData == null)
return null;

if(imageData.length > 0) {
bm = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
if(bm != null) {
drawableMap.put(sURL, bm);
}
return bm;
}
else {
return null;
}
}

public void fetchBitmapOnThread(final String sURL, final ImageView imageView) {
if (drawableMap.containsKey(sURL)) {
imageView.setImageBitmap((Bitmap) drawableMap.get(sURL));
}

final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
imageView.setImageBitmap((Bitmap) message.obj);
}
};

Thread thread = new Thread() {
@Override
public void run() {
Bitmap bitmap = fetchBitmap(sURL);
Message message = handler.obtainMessage(1, bitmap);
handler.sendMessage(message);
}
};
thread.start();
}


@SuppressWarnings("unused")
public static byte[] ThumbImg(String imgUrl)
{

//first check in the cache, if not available then store in the sd card memory
HttpURLConnection connection = null;
String userAgent = null;

try
{
URL url = new URL(imgUrl);
connection = ( HttpURLConnection ) url.openConnection();
if(userAgent != null) {
connection.setRequestProperty("User-Agent", userAgent);
}
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int CHUNKSIZE = 8192; //size of fixed chunks
int BUFFERSIZE = 1024; //size of reading buffer


int bytesRead = 0;
byte[] buffer = new byte[BUFFERSIZE]; //initialize buffer
byte[] fixedChunk = new byte[CHUNKSIZE]; //initialize 1st chunk
ArrayList<byte[]> BufferChunkList = new ArrayList<byte[]>(); // List of chunk data
int spaceLeft = CHUNKSIZE;
int chunkIndex = 0;

DataInputStream in = new DataInputStream(connection.getInputStream() );

while( ( bytesRead = in.read( buffer ) ) != -1 ) { //loop until the DataInputStream is completed
if(bytesRead > spaceLeft) {
//copy to end of current chunk
System.arraycopy(buffer, 0, fixedChunk, chunkIndex, spaceLeft);
BufferChunkList.add(fixedChunk);

//create a new chunk, and fill in the leftover
fixedChunk = new byte[CHUNKSIZE];
chunkIndex = bytesRead - spaceLeft;
System.arraycopy(buffer, spaceLeft, fixedChunk, 0, chunkIndex);
} else {
//plenty of space, just copy it in
System.arraycopy(buffer, 0, fixedChunk, chunkIndex, bytesRead);
chunkIndex = chunkIndex + bytesRead;
}
spaceLeft = CHUNKSIZE - chunkIndex;
}

if (in != null) {
in.close();
}

// copy it all into one big array
int responseSize = (BufferChunkList.size() * CHUNKSIZE) + chunkIndex;
Log.d("response size",""+responseSize);
byte[] responseBody = new byte[responseSize];
int index = 0;
for(byte[] b : BufferChunkList) {
System.arraycopy(b, 0, responseBody, index, CHUNKSIZE);
index = index + CHUNKSIZE;
}
System.arraycopy(fixedChunk, 0, responseBody, index, chunkIndex);

return responseBody;


}catch(SocketTimeoutException se)
{

}
catch(Exception e)
{

e.printStackTrace();
}finally
{
if(connection!=null)
connection.disconnect();
}

return null;
}

}

这是我正在使用的代码,它适用于较小的图像但不适用于大图像。问题是什么以及如何解决?

谢谢

最佳答案

将位图存储在内存中并不总是一个好主意。如果您真的想这样做,请尝试为您的 map 使用 SoftReference。 Check this

将 map 的值参数设置为 SoftReference<Bitmap> .然后在 map 中搜索时使用此代码段

@SuppressWarnings("unchecked")
public class DrawableManager {

@SuppressWarnings("rawtypes")
private final Map<String, SoftReference<Bitmap>> drawableMap;

@SuppressWarnings("rawtypes")
private DrawableManager() {
drawableMap = new HashMap<String, SoftReference<Bitmap>>();
}

static private DrawableManager _instance;

static public DrawableManager getInstance() {
if(_instance == null) {
_instance = new DrawableManager();
}
return _instance;
}

public Bitmap fetchBitmap(final String sURL) {
if(sURL.length() == 0)
return null;
Bitmap bm = null;
SoftReference<Bitmap> reference = drawbaleM.get(imagePath);
if(reference != null) bm = reference.get();
if(bm != null) {
return bm;
}

byte[] imageData = ThumbImg(sURL);

if(imageData == null)
return null;

if(imageData.length > 0) {
bm = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
if(bm != null) {
drawableMap.put(sURL, bm);
}
return bm;
}
else {
return null;
}
}

public void fetchBitmapOnThread(final String sURL, final ImageView imageView) {
if (drawableMap.containsKey(sURL)) {
imageView.setImageBitmap((Bitmap) drawableMap.get(sURL));
}

final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
imageView.setImageBitmap((Bitmap) message.obj);
}
};

Thread thread = new Thread() {
@Override
public void run() {
Bitmap bitmap = fetchBitmap(sURL);
Message message = handler.obtainMessage(1, bitmap);
handler.sendMessage(message);
}
};
thread.start();
}


@SuppressWarnings("unused")
public static byte[] ThumbImg(String imgUrl)
{

//first check in the cache, if not available then store in the sd card memory
HttpURLConnection connection = null;
String userAgent = null;

try
{
URL url = new URL(imgUrl);
connection = ( HttpURLConnection ) url.openConnection();
if(userAgent != null) {
connection.setRequestProperty("User-Agent", userAgent);
}
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int CHUNKSIZE = 8192; //size of fixed chunks
int BUFFERSIZE = 1024; //size of reading buffer


int bytesRead = 0;
byte[] buffer = new byte[BUFFERSIZE]; //initialize buffer
byte[] fixedChunk = new byte[CHUNKSIZE]; //initialize 1st chunk
ArrayList<byte[]> BufferChunkList = new ArrayList<byte[]>(); // List of chunk data
int spaceLeft = CHUNKSIZE;
int chunkIndex = 0;

DataInputStream in = new DataInputStream(connection.getInputStream() );

while( ( bytesRead = in.read( buffer ) ) != -1 ) { //loop until the DataInputStream is completed
if(bytesRead > spaceLeft) {
//copy to end of current chunk
System.arraycopy(buffer, 0, fixedChunk, chunkIndex, spaceLeft);
BufferChunkList.add(fixedChunk);

//create a new chunk, and fill in the leftover
fixedChunk = new byte[CHUNKSIZE];
chunkIndex = bytesRead - spaceLeft;
System.arraycopy(buffer, spaceLeft, fixedChunk, 0, chunkIndex);
} else {
//plenty of space, just copy it in
System.arraycopy(buffer, 0, fixedChunk, chunkIndex, bytesRead);
chunkIndex = chunkIndex + bytesRead;
}
spaceLeft = CHUNKSIZE - chunkIndex;
}

if (in != null) {
in.close();
}

// copy it all into one big array
int responseSize = (BufferChunkList.size() * CHUNKSIZE) + chunkIndex;
Log.d("response size",""+responseSize);
byte[] responseBody = new byte[responseSize];
int index = 0;
for(byte[] b : BufferChunkList) {
System.arraycopy(b, 0, responseBody, index, CHUNKSIZE);
index = index + CHUNKSIZE;
}
System.arraycopy(fixedChunk, 0, responseBody, index, chunkIndex);

return responseBody;


}catch(SocketTimeoutException se)
{

}
catch(Exception e)
{

e.printStackTrace();
}finally
{
if(connection!=null)
connection.disconnect();
}

return null;
}

}

请注意,这并不能保证从 OOM 中解脱出来。显示大位图并不总是一个好主意。

您可以选择的另一个选项是使用 BitmapFactory.Options inSampleSize争论

关于android - 由于位图大小过大导致内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5321579/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com