安卓文件上传崩溃问题

3
以下代码将文件上传到服务器:
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

public String uploadFileForStorage(String serverUrl, String filePath) {
StringBuilder responseMsg = new StringBuilder();
    try {
        final File file = new File(filePath);
        HttpParams httpParameters = new BasicHttpParams();
        // Set the timeout in milliseconds until a connection is
        // established.
        HttpConnectionParams.setConnectionTimeout(httpParameters, UPLOAD_CONNECTION_TIME_OUT);
        // Set the default socket timeout (SO_TIMEOUT)
        // in milliseconds which is the timeout for waiting for data.
        HttpConnectionParams.setSoTimeout(httpParameters, UPLOAD_SOCKET_TIME_OUT);

        HttpClient httpClient = new DefaultHttpClient(httpParameters);

        if (serverUrl.contains("?")) {
             serverUrl = Utils.getProperUrlWithOutEncode(serverUrl);
        }

        HttpPost postRequest = new HttpPost(serverUrl);
        FileBody bin = new FileBody(file);

        CustomMultiPartEntity multipartContent = new CustomMultiPartEntity(new ProgressListener() {
                        @Override
                        public void transferred(long num) {
                            total = total + num;
                        }
                    });
                    multipartContent.addPart(CUSTOM_FILE_TAG, bin);
                    postRequest.setEntity(multipartContent);
                    HttpResponse response = httpClient.execute(postRequest);
                    if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
                        String sResponse;
                        while ((sResponse = reader.readLine()) != null) {
                            responseMsg = responseMsg.append(sResponse);
                        }
                    } else {
                        responseMsg = responseMsg.append(String.valueOf(response.getStatusLine().getStatusCode()));
                    }
                } catch (Exception e) {
                    isError = true;
                }
                return responseMsg.toString();
            }

        }

正在从平板电脑SD卡上传文件。 以上代码在多个安卓平板电脑上运行良好,如三星Galaxy Note 10.1和Micromax Funbook 10英寸,但在上传文件到三星P6200时会崩溃。崩溃不会立即发生,而是在上传5-10%后才会出现。

之前,在三星P6200上也能正常上传。我对平板电脑进行了恢复出厂设置,但上传时的崩溃问题仍然存在。此外,logcat中没有显示OutOfMemoryException,而是显示了一个类文件中的NullPointerException,这不应该出现。假设问题是HeapSize问题,我该如何处理。

使用上述代码,我能够通过SIM(3G / WiFi)从SD卡上传高达400 MB的文件,使用安卓平板电脑,如三星Galaxy Note 10.1和Micromax Funbook 10。

添加以下代码是否有帮助?

HttpConnectionParams.setSocketBufferSize(httpParameters, 8192); 
// or any value other than //8192

2
你能否发布错误情况下的logcat?这可能有助于确定错误,但无论如何,请查看http://stackoverflow.com/questions/4455006/posting-a-large-file-in-android。 - Vrashabh Irde
1
日志显示在一个不应该出现的类文件中发生了NullPointerException。你确实需要包含这样的信息。 - Reuben Scratton
Reuben Scratton:实际上,在仅包含一个按钮的布局中点击该按钮以启动上传过程的Activity中,会收到NullPointerException异常。在上传流程成功的情况下,不会抛出NullPointerException。这就是不在问题中提供详细信息的原因。我认为NullPointerException并不是崩溃的真正原因,否则它将在所有情况下都被抛出。 - chiranjib
尝试在疑似位置添加一些日志,比如循环之前、循环内部和循环外部等。通过logcat的结果,您可以了解已经成功执行了多少步骤以及您的应用程序在哪里崩溃了。 - dinesh sharma
你应该使用Buffer来上传文件。在你的代码中,请扩展FileBody mFileBody = new FileBody(fileName) {writeTo()...}; - Luc
1个回答

0
                postRequest.setEntity(multipartContent);
                HttpResponse response = httpClient.execute(postRequest);
如果怀疑堆问题,则应检查您的httpclient的实现/源代码。我猜你正在使用apache客户端,所以你可以在那里检查。
有两个内存问题。
当文件标签映射到内存中(在使用套接字之前),使用了多大和什么样的缓冲区?您可能需要深入挖掘将文件映射到内存的代码,并使其符合较小的可用内存/缓冲区大小。
一旦套接字开始上传,client.execute使用另一个缓冲区循环从文件内存中读取并写入用于上传的套接字。除了在套接字缓冲区大小上进行配置之外,您还可以尝试使用“分块编码”(流式传输)进行上传。转储您的标头,您应该能够看到您使用的Mime Multipart表单是否导致了“分块编码”的http标头。
对于分块{{link1:example with httpUrlConnection}},这将适用于大型上传。在源代码中查找“ChunkedStreamingMode”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接