2010-04-08 12 views
6

मुझे एक ही समस्या है as described here, लेकिन मैं कुछ और विवरण प्रदान करूंगा। एंड्रॉइड में एक वीडियो अपलोड करने का प्रयास करते समय, मैं इसे स्मृति में पढ़ रहा हूं, और यदि वीडियो बड़ा है तो मुझे आउटऑफमेमरी एरर मिलता है।एंड्रॉइड: आउटऑफमेमरी वीडियो अपलोड करते समय त्रुटि - कैसे सबसे अच्छा हिस्सा है?

यहाँ मेरी कोड है:

// 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 

मुझे लगता है कि as @DroidIn suggests, मैं मात्रा में इसे अपलोड करने की जरूरत है। लेकिन (नौसिखिया प्रश्न चेतावनी) क्या इसका मतलब यह है कि मुझे एकाधिक पोस्टमेड अनुरोध करना चाहिए, और सर्वर अंत में फाइल को एक साथ चिपका देना चाहिए? या क्या मैं बाइटस्ट्रीम को टुकड़ों में स्मृति में लोड कर सकता हूं, और एंड्रॉइड कोड में इसे एक साथ चिपका सकता हूं?

यदि कोई मुझे सर्वश्रेष्ठ दृष्टिकोण के रूप में एक सुराग दे सकता है, तो मैं बहुत आभारी रहूंगा।

उत्तर

3

आपको पूरी फ़ाइल को स्मृति में प्राप्त करने की आवश्यकता नहीं है, फिर उसे एक बार अपलोड करें। कॉल कनेक्शन .getOutputStream() और लिखें() भागों में बाइट्स।

+0

मूल रूप से, कनेक्शन के साथ जुड़े 'आउटपुटस्ट्रीम' के साथ readBytes() में 'ByteArrayOutputStream' को प्रतिस्थापित करें। – wds

10

जिम ब्लैकलर बिल्कुल सही है। आपके पास बाइट [] में स्मृति में पूरा वीडियो नहीं हो सकता है। तो आपको फ़ाइल को बाइट [] पर नहीं पढ़ना चाहिए, लेकिन सीधे HttpUrlConnectio.getOutputStream() पर।

लेकिन इसके बाद भी आप आउटऑफमेमरी प्राप्त करेंगे क्योंकि HttpUrlConnection स्मृति में सभी आउटपुट डेटा को कैश करता है और जब आप पूर्ण लेखन कर रहे होते हैं तो इसे केवल नेटवर्क पर भेजता है।

इस व्यवहार को ओवरराइड करने के लिए आप HttpUrlConnection.setChunkedStreamingMode() या HttpUrlConnection.setFixedLengthStreamingMode() का उपयोग कर सकते हैं। यदि आपका सर्वर स्ट्रीम खंड स्वीकार करता है तो आप setChunkedStreamingMode() का उपयोग कर सकते हैं। अन्यथा आपको setFixedLengthStreamingMode का उपयोग करना होगा। SetFixedLengthStreamingMode का उपयोग करने के लिए आपको डेटा स्ट्रीमिंग शुरू करने से पहले सटीक सामग्री की लंबाई जानने की आवश्यकता होगी, इसलिए यह थोड़ा मुश्किल है।

इस बिंदु पर आउटऑफ मेमरी नहीं।

यदि आपके पास फ़ाइल में आपका वीडियो है तो आप एक और दृष्टिकोण चुन सकते हैं, और अधिक सरल। HttpClient और FileBody का उपयोग करें How to send HTTP POST request and receive response?। मुझे लगता है कि वे उपरोक्त सभी विधियों को लागू करते हैं और आपको इसके बारे में चिंता करने की आवश्यकता नहीं होगी।

+0

धन्यवाद, @ फेडर, यह वास्तव में सहायक है। – neevek

+0

क्या आप कृपया सुझाव दे सकते हैं कि कौन सा सबसे अच्छा है? अभी मैं भाग बनाने के लिए आर एंड डी कर रहा हूं और इसे एक-एक करके अपलोड कर रहा हूं। क्या यह अच्छा तरीका है? –

+0

@ फेडर मुझे कैसे पता चलेगा कि मेरा अपाचे सर्वर धाराओं को स्वीकार करता है या नहीं? मुझे पता है कि मेरे पास 'setChunkedStreamingMode()' सेट है, मुझे कोई डेटा नहीं मिला है: http://stackoverflow.com/q/15913844/317889 – HGPB

1

बस एक छोटे से ध्यान दें:

setChunkedStreamingMode और setFixedeLengthStreamingMode एंड्रॉयड 2.1 में काम नहीं करते, वे 2.0 और 2.2

+0

मेरे विपरीत स्थिति थी: setChunkedStreamingMode 2.3.3 में काम करता है और 2.2 में काम नहीं करता है। ऐसा लगता है कि हमें v। <2.3 और HttpUrlConnection> 2.2 डबल कोडिंग के लिए HttpClient का उपयोग करना चाहिए :( –

0

में सही काम करते हैं इसका बेहतर भागों में फ़ाइल विभाजित करें और अपलोड करने के लिए। सर्वर की तरफ भागों को मर्ज करें।

संबंधित मुद्दे