Android Spring File Upload OutofMemory

android, out-of-memory, post, rest, spring

Solution

Analyzing the code, it seems Spring for Android buffers its data before sending it - that's why your OOE. There is a trick however (but so far I've made it possible to work only for API level 9 above): you can disable the buffering for its connection factory but ONLY if the RestTemplate has no `ClientHttpRequestInterceptor` list set (now how stupid is that ?) - lucky you as you didn't set one. So in your case the situation is very simple, just call `factory.setBufferRequestBody(false);` after you've instantiated it.

Problem

I am trying to use the following code to upload a file to a rest api. This code works fine for files up to around 20MB, but bigger files will give an `OutOfMemoryError`. I am trying to chunk the request and use a multipart-form request so that I don't have to keep the whole file in memory, but maybe the chunks are too big? Any help is greatly appreciated. ``` final File file = new File(filePath); HttpHeaders header = new HttpHeaders(); header.add("x-haiku-auth", HaikuAPI.getAuthHeader()); header.setContentType(MediaType.MULTIPART_FORM_DATA); UriComponentsBuilder builder = UriComponentsBuilder.fromUriString( "https://" + HaikuAPI.getDomain() + "/api/assignments") .pathSegment(assignmentID + "", "submit"); URI url = builder.build().toUri(); MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>(); parts.add("message[subject]", "Assignment Completed"); parts.add("message[body]", message); parts.add("message[assignment_id]", assignmentID + ""); Uri uri = Uri.fromFile(file); InputStreamResource res = new InputStreamResource(context.getContentResolver().openInputStream(uri)) { @Override public String getFilename() throws IllegalStateException { return file.getName(); } @Override public long contentLength() throws IOException { return file.length(); } }; parts.add("files[][file]", res); parts.add("files[][filename]", file.getName()); SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setChunkSize(1024); RestTemplate restTemplate = new RestTemplate(factory); restTemplate.getMessageConverters().add(new FormHttpMessageConverter()); HttpEntity<Object> request = new HttpEntity<Object>(parts, header); restTemplate.postForLocation(url, request); Log.e("f", "finished"); return null; ``` Error: `dalvikvm-heap: Out of memory on a 67102090-byte allocation.`

Original source

Related problems