2016-06-16 9 views
0

Я пытаюсь загрузить файл на сервер с использованием многострочной формы. Поскольку API 23 Android устарел от HTTP-библиотеки Apache.Загрузка файлов с несколькими файлами в Android в 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 является:

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

Однако, похоже, OkHttp не так уж велика, когда речь идет о загрузка файлов. Множество тайм-аутов и, кажется, создает несколько слоев абстракций (источников и стоков) и имеет этот AsyncTimeout, который срабатывает, пока данные файла все еще записываются через сокет.

Есть ли рекомендации по выполнению многопользовательских загрузок файлов с Android, которые работают с API 23 и далее. Я знаю, что могу включить библиотеку устаревших 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 не работает в сокете, но в приложении со сном(), и он срабатывает до того, как ответ возвращается с сервера, даже если сокет, который он сам не отключился. – dg428

Смежные вопросы