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();
            }

        }

正在从 Tablet SDCard 上传文件。上面的代码适用于三星 Galaxy Note 10.1 和 Micromax Funbook 10 英寸等多台 Android 平板电脑,但在三星 P6200 中上传文件时崩溃。崩溃不会立即发生,而是在上传 5-10% 后发生。

以前,上传在三星 P6200 上也可以正常工作。我将平板电脑恢复出厂设置,但上传时崩溃仍然存在。此外,OutOfMemoryException 未显示在 logcat 中。日志在不应显示的类文件中显示 NullPointerException。假设问题是 HeapSize 问题,我该如何处理该问题。

使用上面的代码,我可以使用 SIM(3G / WiFi)和三星 Galaxy Note 10.1 和 Micromax Funbook 10 等 Android 平板电脑从 SDCard 上传高达 400 MB 的文件。

应该添加以下代码行有帮助吗?

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

1 回答 1

0
                postRequest.setEntity(multipartContent);
                HttpResponse response = httpClient.execute(postRequest);

如果怀疑堆问题,那么您应该检查您的 httpclient 的实现/源代码。我猜你正在使用 apache 客户端,所以你可以在那里检查。

有2个内存问题。

当文件标签被映射到内存时(在使用套接字之前),使用了多大和什么样的缓冲区?您可能必须深入研究将文件映射到内存并使其符合较小的可用内存/缓冲区大小的代码。

一旦套接字开始进行上传,client.execute 使用另一个缓冲周期从文件内存中读取并写入用于上传的套接字。除了在套接字缓冲区大小上使用配置之外,您可能还想在上传时尝试“分块编码”(流式传输)。转储您的标头,您应该能够查看您使用的 Mime Multipart 表单是否导致“分块编码”的 http 标头。

对于httpUrlConnection 的分块示例,它适用于大上传。在源代码中找到“ChunkedStreamingMode”。

于 2013-07-23T16:19:42.057 回答