微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

@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参数

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐