2012-09-14 23 views
2

我们正在为Android编写应用程序,当我们正在发送PDF文件(通过HTTP POST)服务器,应用程序崩溃与此异常显示:的OutOfMemoryError发送PDF HTTP邮政

09-14 15:31:59.253: D/dalvikvm(22978): GC_EXPLICIT freed 437 objects/1236120 bytes in 47ms 
09-14 15:31:59.296: D/dalvikvm(22978): GC_FOR_MALLOC freed 29 objects/1648 bytes in 45ms 
09-14 15:31:59.316: I/dalvikvm-heap(22978): Grow heap (frag case) to 13.987MB for 5171605-byte allocation 
09-14 15:31:59.359: D/dalvikvm(22978): GC_FOR_MALLOC freed 0 objects/0 bytes in 40ms 
09-14 15:31:59.394: D/dalvikvm(22978): GC_FOR_MALLOC freed 2 objects/48 bytes in 27ms 
09-14 15:31:59.410: I/dalvikvm-heap(22978): Grow heap (frag case) to 20.563MB for 6895468-byte allocation 
09-14 15:31:59.453: D/dalvikvm(22978): GC_FOR_MALLOC freed 0 objects/0 bytes in 41ms 
09-14 15:32:00.089: D/dalvikvm(22978): GC_FOR_MALLOC freed 5 objects/120 bytes in 23ms 
09-14 15:32:00.117: I/dalvikvm-heap(22978): Grow heap (frag case) to 33.715MB for 13790920-byte allocation 
09-14 15:32:00.164: D/dalvikvm(22978): GC_FOR_MALLOC freed 0 objects/0 bytes in 43ms 
09-14 15:32:00.214: D/dalvikvm(22978): GC_FOR_MALLOC freed 13 objects/6895864 bytes in 26ms 
09-14 15:32:00.214: I/dalvikvm-heap(22978): Forcing collection of SoftReferences for 13790920-byte allocation 
09-14 15:32:00.242: D/dalvikvm(22978): GC_FOR_MALLOC freed 0 objects/0 bytes in 25ms 
09-14 15:32:00.242: E/dalvikvm-heap(22978): Out of memory on a 13790920-byte allocation. 
09-14 15:32:00.242: I/dalvikvm(22978): "main" prio=5 tid=1 RUNNABLE JIT 
09-14 15:32:00.242: I/dalvikvm(22978): | group="main" sCount=0 dsCount=0 s=N obj=0x4001d8b0 self=0xcd28 
09-14 15:32:00.242: I/dalvikvm(22978): | sysTid=22978 nice=0 sched=0/0 cgrp=default handle=-1345017808 
09-14 15:32:00.242: I/dalvikvm(22978): at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:~45) 
09-14 15:32:00.242: I/dalvikvm(22978): at java.nio.ReadWriteHeapByteBuffer.<init>(ReadWriteHeapByteBuffer.java:47) 
09-14 15:32:00.242: I/dalvikvm(22978): at java.nio.BufferFactory.newByteBuffer(BufferFactory.java:49) 
09-14 15:32:00.242: I/dalvikvm(22978): at java.nio.ByteBuffer.allocate(ByteBuffer.java:52) 
09-14 15:32:00.242: I/dalvikvm(22978): at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:317) 
09-14 15:32:00.242: I/dalvikvm(22978): at java.nio.charset.Charset.encode(Charset.java:692) 
09-14 15:32:00.242: I/dalvikvm(22978): at java.lang.String.getBytes(String.java:903) 
09-14 15:32:00.242: I/dalvikvm(22978): at vetic.iventory.cds.CustomEntity.getContentLength(CustomEntity.java:69) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.protocol.RequestContent.process(RequestContent.java:79) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:160) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
09-14 15:32:00.242: I/dalvikvm(22978): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
09-14 15:32:00.242: I/dalvikvm(22978): at vetic.iventory.cds.CustomHttpClient.executeHttpCustomPost(CustomHttpClient.java:111) 
09-14 15:32:00.242: I/dalvikvm(22978): at sql.vetil.edel.EtatDesLieuxBDD.sendFile(EtatDesLieuxBDD.java:176) 
09-14 15:32:00.242: I/dalvikvm(22978): at sql.vetil.edel.EtatDesLieuxBDD.getReturnServer(EtatDesLieuxBDD.java:212) 
09-14 15:32:00.242: I/dalvikvm(22978): at vetic.iventory.cds.P8$3.onClick(P8.java:224) 
09-14 15:32:00.242: I/dalvikvm(22978): at android.view.View.performClick(View.java:2408) 
09-14 15:32:00.246: I/dalvikvm(22978): at android.view.View$PerformClick.run(View.java:8818) 
09-14 15:32:00.246: I/dalvikvm(22978): at android.os.Handler.handleCallback(Handler.java:587) 
09-14 15:32:00.246: I/dalvikvm(22978): at android.os.Handler.dispatchMessage(Handler.java:92) 
09-14 15:32:00.246: I/dalvikvm(22978): at android.os.Looper.loop(Looper.java:123) 
09-14 15:32:00.246: I/dalvikvm(22978): at android.app.ActivityThread.main(ActivityThread.java:4627) 
09-14 15:32:00.246: I/dalvikvm(22978): at java.lang.reflect.Method.invokeNative(Native Method) 
09-14 15:32:00.246: I/dalvikvm(22978): at java.lang.reflect.Method.invoke(Method.java:521) 
09-14 15:32:00.246: I/dalvikvm(22978): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
09-14 15:32:00.246: I/dalvikvm(22978): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
09-14 15:32:00.246: I/dalvikvm(22978): at dalvik.system.NativeStart.main(Native Method) 
09-14 15:32:00.246: D/AndroidRuntime(22978): Shutting down VM 
09-14 15:32:00.246: W/dalvikvm(22978): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0) 
09-14 15:32:00.253: E/AndroidRuntime(22978): FATAL EXCEPTION: main 
09-14 15:32:00.253: E/AndroidRuntime(22978): java.lang.OutOfMemoryError 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:45) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.nio.ReadWriteHeapByteBuffer.<init>(ReadWriteHeapByteBuffer.java:47) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.nio.BufferFactory.newByteBuffer(BufferFactory.java:49) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.nio.ByteBuffer.allocate(ByteBuffer.java:52) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:317) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.nio.charset.Charset.encode(Charset.java:692) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.lang.String.getBytes(String.java:903) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at vetic.iventory.cds.CustomEntity.getContentLength(CustomEntity.java:69) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.protocol.RequestContent.process(RequestContent.java:79) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:160) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:464) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at vetic.iventory.cds.CustomHttpClient.executeHttpCustomPost(CustomHttpClient.java:111) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at sql.vetil.edel.EtatDesLieuxBDD.sendFile(EtatDesLieuxBDD.java:176) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at sql.vetil.edel.EtatDesLieuxBDD.getReturnServer(EtatDesLieuxBDD.java:212) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at vetic.iventory.cds.P8$3.onClick(P8.java:224) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at android.view.View.performClick(View.java:2408) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at android.view.View$PerformClick.run(View.java:8818) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at android.os.Handler.handleCallback(Handler.java:587) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at android.os.Handler.dispatchMessage(Handler.java:92) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at android.os.Looper.loop(Looper.java:123) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at android.app.ActivityThread.main(ActivityThread.java:4627) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.lang.reflect.Method.invokeNative(Native Method) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at java.lang.reflect.Method.invoke(Method.java:521) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
09-14 15:32:00.253: E/AndroidRuntime(22978): at dalvik.system.NativeStart.main(Native Method) 
09-14 15:32:19.394: I/Process(22978): Sending signal. PID: 22978 SIG: 9 
09-14 15:32:19.554: D/dalvikvm(23043): GC_EXTERNAL_ALLOC freed 973 objects/71752 bytes in 31ms 
09-14 15:32:21.046: W/KeyCharacterMap(23043): No keyboard for id 0 
09-14 15:32:21.046: W/KeyCharacterMap(23043): Using default keymap: /system/usr/keychars/qwerty.kcm.bin 

的错误在该片段中,用于计数该数据的大小,以发送被升高(这意味着该文件还没有准备好发送):

try { 
    size++; 
    File f = new File(complexParametres.get(key)); // File to send 
    InputStream is = new FileInputStream(f); 
    System.gc(); 
    byte b[] = new byte[(int) f.length()]; 
    is.read(b); 
    size += Base64.encodeBytes(b).getBytes().length; // Parameter encoded in Base64 
    is.close(); 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

该错误是在这条线:

size += Base64.encodeBytes(b).getBytes().length; 

你知道如何避免这个问题吗?

非常感谢。

+5

流支持读/写小块数据。你不应该把整个事情都看成是记忆,编码和发送。阅读一个块,编码和发送并重复,直到完成。 – zapl

+0

@zapl说什么,检查''android.util.Base64OutputStream''。 – harism

+0

您的错误表明您尝试在设备上分配13790920字节〜13790 kb〜13 MB的堆,堆大小通常在16-40MB范围内。正如其他人所说,不要一次分配。还要考虑(发送)GPRS连接可能只有64kbit/s。 –

回答

2

检查android.util.Base64OutputStream。 - harism

下面的代码使用它来发送一个文件Base64编码在任何OutputStream。请致电sendBase64Encoded(yourFile, httpPostOutputstream)

该实现使用4k字节发送任意大小的文件。

/** generic InputStream to OutputStream copy */ 
public static void streamCopy(InputStream in, OutputStream out) throws IOException { 
    byte[] buffer = new byte[4 * 1024]; 
    int read; 
    while ((read = in.read(buffer)) != -1) { 
     out.write(buffer, 0, read); 
    } 
} 

/** close stuff that can be null, exceptions ignored */ 
public static void close(Closeable c) { 
    if (c != null) 
     try { 
      c.close(); 
     } catch (IOException ignored) { 
      // silence 
     } 
} 

/** does NOT close out */ 
public static void sendBase64Encoded(String filename, OutputStream out) { 
    File inputFile = new File(filename); 
    FileInputStream source = null; 
    Base64OutputStream target = null; 
    try { 
     source = new FileInputStream(inputFile); 
     target = new Base64OutputStream(out, Base64.NO_CLOSE); 
     streamCopy(source, target); 
     target.flush(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     close(source); 
     close(target); 
    } 
}