2016-06-16 3 views
0

멀티 파트 양식을 사용하여 서버에 파일을 업로드하려고합니다. API 23 이후로 Android는 Apache HTTP 라이브러리를 더 이상 사용하지 않습니다. Android Multipart Form Marshmallow에서 파일 업로드

내가 그렇게처럼 내 파일 업로드를 할 OkHttp 사용으로 전환 :

 RequestBody requestBody = new MultipartBody.Builder() 
       .setType(MultipartBody.FORM) 
       .addFormDataPart(name, fileName, requestBodyPart) 
       .build(); 

     Request request = new Request.Builder() 
       .url(url) 
       .post(requestBody) 
       .build(); 

을 그리고 requestBodyPart은 다음과 같습니다 OkHttp 그것이 올 때 크지 않다처럼 그러나

 requestBodyPart = new RequestBody() { 
      @Override 
      public MediaType contentType() { 
       return MediaType.parse(contentType); 
      } 

      @Override 
      public void writeTo(BufferedSink sink) throws IOException { 
       try { 
        if (sink.writeAll(Okio.source(inputStream)) == 0) { 
         throw new IOException("Empty File!"); 
        } 
       } finally { 
        MiscUtils.closeCloseable(inputStream); 
       } 
      } 
     }; 

것 같습니다 파일 업로드. 많은 타임 아웃과 추상화 (소스와 싱크)의 여러 레이어를 만드는 것으로 보이며 파일 데이터가 여전히 소켓을 통해 쓰여지는 동안이 AsyncTimeout이 발생합니다.

API 23 이상에서 작동하는 Android에서 멀티 파일 업로드를 수행하기위한 권장 사항이 있습니까? HTTP 레거시 라이브러리를 포함 할 수 있지만 제거 된 이후로는 그렇게하지 않는 것이 좋습니다. 아니면 OkHttp의 성능을 향상시킬 수있는 방법이 있습니까?

답변

0

이것은 당신의 응답을

String name = ... 
File file = ... 
MediaType mediaType = MediaType.parse(...) 
OkHttpClient httpClient = ... 
Request request = new Request.Builder() 
     .url(url) 
     .post(new MultipartBuilder().type(MultipartBuilder.FORM) 
            .addFormDataPart(name, 
                file.getName(), 
                RequestBody.create(mediaType, file)) 
            .build()) 
     .build(); 
try { 
    Response response = httpClient.newCall(request).execute(); 
} catch (IOException e) { 
    // handle error 
} 
+0

덕분에 작동합니다. 예, 정확하게 사용하고 있습니다. 문제는 약간 큰 파일이나 파일을 쓰는 동안 시간 초과가 발생하는 느린 네트워크에서 성능이 없다는 것입니다. – dg428

+0

소켓에 데이터가 기록 될 때까지 시간 초과가 발생하지 않아야합니다. 'OkHttpClient httpClient = new OkHttpClient();를 사용하여 제한 시간을 구성 할 수 있습니다. httpClient.setConnectTimeout (30, TimeUnit.SECONDS); httpClient.setReadTimeout (30, TimeUnit.SECONDS); ' –

+0

실제로 3 분 이상 설정했습니다. 큰 파일의 마지막 바이트가 여전히 AsyncTimeout이 실행되는 소켓으로 전송되지 않습니다 (기본 소켓이 일부 데이터를 버퍼링하기 때문에). AsyncTimeout은 소켓에서는 작동하지 않지만 응용 프로그램에서는 sleep()을 사용하여 응답을 받기 전에 서버에서 응답을 받기 전에 실행됩니다. 소켓 자체가 시간 초과되지 않았더라도 – dg428

관련 문제