Android: OutOfMemoryError при загрузке видео – как лучше всего кушать?

У меня такая же проблема, как описано здесь , но я расскажу еще несколько деталей. При попытке загрузить видео на Android я читаю его в памяти, и если видео большое, я получаю OutOfMemoryError.

Вот мой код:

// get bytestream to upload videoByteArray = getBytesFromFile(cR, fileUriString); public static byte[] getBytesFromFile(ContentResolver cR, String fileUriString) throws IOException { Uri tempuri = Uri.parse(fileUriString); InputStream is = cR.openInputStream(tempuri); byte[] b3 = readBytes(is); is.close(); return b3; } public static byte[] readBytes(InputStream inputStream) throws IOException { ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); // this is storage overwritten on each iteration with bytes int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; int len = 0; while ((len = inputStream.read(buffer)) != -1) { byteBuffer.write(buffer, 0, len); } return byteBuffer.toByteArray(); } 

И вот трассировка (ошибка выбрасывается на byteBuffer.write(buffer, 0, len) ):

 04-08 11:56:20.456: ERROR/dalvikvm-heap(6088): Out of memory on a 16775184-byte allocation. 04-08 11:56:20.456: INFO/dalvikvm(6088): "IntentService[UploadService]" prio=5 tid=17 RUNNABLE 04-08 11:56:20.456: INFO/dalvikvm(6088): | group="main" sCount=0 dsCount=0 s=N obj=0x449a3cf0 self=0x38d410 04-08 11:56:20.456: INFO/dalvikvm(6088): | sysTid=6119 nice=0 sched=0/0 cgrp=default handle=4010416 04-08 11:56:20.456: INFO/dalvikvm(6088): at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:~93) 04-08 11:56:20.456: INFO/dalvikvm(6088): at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:218) 04-08 11:56:20.456: INFO/dalvikvm(6088): at com.android.election2010.UploadService.readBytes(UploadService.java:199) 04-08 11:56:20.456: INFO/dalvikvm(6088): at com.android.election2010.UploadService.getBytesFromFile(UploadService.java:182) 04-08 11:56:20.456: INFO/dalvikvm(6088): at com.android.election2010.UploadService.doUploadinBackground(UploadService.java:118) 04-08 11:56:20.456: INFO/dalvikvm(6088): at com.android.election2010.UploadService.onHandleIntent(UploadService.java:85) 04-08 11:56:20.456: INFO/dalvikvm(6088): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:30) 04-08 11:56:20.456: INFO/dalvikvm(6088): at android.os.Handler.dispatchMessage(Handler.java:99) 04-08 11:56:20.456: INFO/dalvikvm(6088): at android.os.Looper.loop(Looper.java:123) 04-08 11:56:20.456: INFO/dalvikvm(6088): at android.os.HandlerThread.run(HandlerThread.java:60) 04-08 11:56:20.467: WARN/dalvikvm(6088): threadid=17: thread exiting with uncaught exception (group=0x4001b180) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): Uncaught handler: thread IntentService[UploadService] exiting due to uncaught exception 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): java.lang.OutOfMemoryError 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:93) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:218) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at com.android.election2010.UploadService.readBytes(UploadService.java:199) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at com.android.election2010.UploadService.getBytesFromFile(UploadService.java:182) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at com.android.election2010.UploadService.doUploadinBackground(UploadService.java:118) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at com.android.election2010.UploadService.onHandleIntent(UploadService.java:85) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:30) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at android.os.Handler.dispatchMessage(Handler.java:99) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at android.os.Looper.loop(Looper.java:123) 04-08 11:56:20.467: ERROR/AndroidRuntime(6088): at android.os.HandlerThread.run(HandlerThread.java:60) 04-08 11:56:20.496: INFO/Process(4657): Sending signal. PID: 6088 SIG: 3 

Я предполагаю, что, как предлагает @DroidIn , мне нужно загрузить его в куски. Но (предупреждение для новичков) это означает, что я должен делать несколько запросов PostMethod и склеить файл вместе на сервере? Или я могу загрузить байтовый поток в память в кусках и склеить его вместе в коде Android?

Если бы кто-нибудь мог дать мне ключ к лучшему подходу, я был бы очень благодарен.

Джим Блэклер абсолютно прав. Вы не можете иметь полное видео в памяти в байте []. Поэтому вы должны читать файл не в байте [], а непосредственно в HttpUrlConnectio.getOutputStream ().

Но даже после этого вы все равно получите OutOfMemory, потому что HttpUrlConnection кэширует все выходные данные в памяти и отправляет их в сеть только после полной записи.

Чтобы переопределить это поведение, вы можете использовать HttpUrlConnection.setChunkedStreamingMode () или HttpUrlConnection.setFixedLengthStreamingMode (). Если ваш сервер принимает куски потоков, вы можете использовать setChunkedStreamingMode (). В противном случае вам придется использовать setFixedLengthStreamingMode. Чтобы использовать setFixedLengthStreamingMode, вам нужно знать точную длину содержимого перед началом потоковой передачи данных, так что это немного сложно.

На данный момент больше нет OutOfMemory.

Если у вас есть видео в файле, вы можете выбрать другой подход, гораздо более простой. Используйте HttpClient и FileBody, как это. Как отправить запрос HTTP POST и получить ответ? , Я думаю, что они реализуют все вышеперечисленные методы, и вам не придется беспокоиться об этом.

Вам не нужно получать весь файл в памяти, а затем загружать его на ходу. Вызовите connection.getOutputStream () и напишите () байты в кусках.

Просто небольшое примечание:

SetChunkedStreamingMode и setFixedeLengthStreamingMode НЕ работают в android 2.1, они отлично работают в версиях 2.0 и 2.2

Лучше разбить файл на части и загрузить. Объедините части на стороне сервера.