android-由于位图较大,导致内存不足异常

android-由于位图较大,导致内存不足异常,第1张

概述由于虚拟内存堆大小有限,我有内存不足的问题.这是我从服务器获取位图的代码:@SuppressWarnings("unchecked")publicclassDrawableManager{@SuppressWarnings("rawtypes")privatefinalMapdrawableMap;@SuppressWarnings("rawtypes")privateDrawableManag

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

@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;    }}

这是我正在使用的代码,在较小的图像上可以正常使用,但对于较大的图像则不能.有什么问题要解决?

谢谢

解决方法:

将位图存储在内存中并非总是一个好主意.如果确实要这样做,请尝试对地图使用SoftReference. Check this

将地图的value参数设置为SoftReference< Bitmap>.然后在地图上搜索时使用此代码段

@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-由于位图较大,导致内存不足异常全部内容,希望文章能够帮你解决android-由于位图较大,导致内存不足异常所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1092755.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存