Search code examples
androidout-of-memorywebp

Outofmemory error when i display webp image on android 2.x with libwebp and ndk


  I use google open source project libwebp to display webp image on android 1.6--android 4.0,and directly decode webp on android 4.0 or above this version, I found that in some android mobilephones such as appo,I will get an outofmemory error when run libwebp lib,and the code which gives error is:int[] pixels = new int[decoded.length / 4]; can anyone suggest me how to avoid this? Here is my code:

  

public static Bitmap getBitmapFromURL(String src) {        
          HttpURLConnection connection = null;        
          Bitmap bmp = null;        
          try {            
               connection = (HttpURLConnection) 
               new URL(src).openConnection();               
               connection.setRequestMethod("GET");           
               connection.setUseCaches(false);            
               connection.setDoInput(true);            
               connection.setDoOutput(true);           
               connection.setRequestProperty("Content-Type", 
                   "image/webp");           
               connection.connect();
          //Send request             
               DataOutputStream wr = new DataOutputStream (                               connection.getOutputStream ());              
               wr.writeBytes ("");             
               wr.flush ();             
               wr.close ();
              //Get Response                  
               BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buf = new byte[4096];           
             while(true) {               
                  String n = rd.readLine();                
                  if(n == null)break;                
                      baos.write(n.getBytes(), 0, n.getByte().length);                     
                  baos.write('\n');            
           }
            byte data[] = baos.toByteArray();                   
 // From the lib's exemple             
            int[] width = new int[] { 0 };           
            int[] height = new int[] { 0 };
            int test = libwebp.WebPGetInfo(data, data.length, width, height); 
// test = 0 ! ! !
            byte[] decoded = libwebp.WebPDecodeARGB(data, data.length, width, height); 

#######################out of memory error is always here         
            int[] pixels = new int[decoded.length / 4];  
####################### 
            ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
            bmp = Bitmap.createBitmap(pixels, width[0], height[0],Bitmap.Config.ARGB_8888);        
             } catch (IOException e) {           
            e.printStackTrace();        }
        return bmp;
    }

Solution

  • Try using System.gc() before creating bitmaps. This will force to garbage collect in Android. This might free up enough memory. If you keep getting out of memory errors, try to find memory leaks in your code and fix it.

    Still not working? Maybe try it in C/C++ in native code. Here you can manage your memory efficiently(if your familiar with C/C++).

    Try something like this:

    public static ByteArrayOutputStream getBytesFromURL(String src) {        
          HttpURLConnection connection = null;        
          ByteArrayOutputStream baos = new ByteArrayOutputStream();       
          try {            
               connection = (HttpURLConnection) 
               new URL(src).openConnection();               
               connection.setRequestMethod("GET");           
               connection.setUseCaches(false);            
               connection.setDoInput(true);            
               connection.setDoOutput(true);           
               connection.setRequestProperty("Content-Type", 
                   "image/webp");           
               connection.connect();
          //Send request             
               DataOutputStream wr = new DataOutputStream (                               connection.getOutputStream ());              
               wr.writeBytes ("");             
               wr.flush ();             
               wr.close ();
              //Get Response                  
               BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));    
               while(true) {               
                  String n = rd.readLine();                
                  if(n == null)break;                
                      baos.write(n.getBytes(), 0, n.getByte().length);                     
                  baos.write('\n');            
               }
               connection.close();
            }catch(Exception q){} //Your exception catching here
               return baos;
    }
    
    public static Bitmap createBitmap(ByteArrayOutputStream baos){
                System.gc();
                byte data[] = baos.toByteArray();                   
    
    
    // From the lib's exemple             
                int[] width = new int[] { 0 };           
                int[] height = new int[] { 0 };
                int test = libwebp.WebPGetInfo(data, data.length, width, height); 
    // test = 0 ! ! !
                byte[] decoded = libwebp.WebPDecodeARGB(data, data.length, width, height);        
                int[] pixels = new int[decoded.length / 4];  
                ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
                bmp = Bitmap.createBitmap(pixels, width[0], height[0],Bitmap.Config.ARGB_8888);        
            return bmp;
        }