Я пытаюсь отправить много изображений на API
, используя okHttp3
и retrofit2
. Я попытался отправить изображения с одного устройства (5 изображений одновременно), и это работало хорошо. Затем я попытался отправить 5 изображений с 5 устройств одновременно, и это работало хорошо, но когда я попытался отправить 30 изображений с 5 устройств, я получил следующую ошибку:
2020-01-17 14:57:07.416 32244-32264/my.example.com.puri W/zygote: Throwing OutOfMemoryError "Failed to allocate a 102554120 byte allocation with 8388608 free bytes and 97MB until OOM, max allowed footprint 174912000, growth limit 268435456"
2020-01-17 14:57:07.422 32244-32264/my.example.com.puri E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: my.example.com.puri, PID: 32244
java.lang.OutOfMemoryError: Failed to allocate a 102554120 byte allocation with 8388608 free bytes and 97MB until OOM, max allowed footprint 174912000, growth limit 268435456
at java.lang.StringFactory.newStringFromBytes(StringFactory.java:178)
at java.lang.StringFactory.newStringFromBytes(StringFactory.java:209)
at okio.Buffer.readString(Buffer.java:620)
at okio.Buffer.readString(Buffer.java:603)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:198)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:135)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Это error
делает не приходят на первое устройство, которое отправляет запрос, скорее оно приходит на то, которое является третьим или последним. Устройство, на котором я сначала нажимаю кнопку send
, всегда работает успешно.
Я также внес эти изменения в Manifest
.
<application
android:hardwareAccelerated="false"
android:largeHeap="true"
>
И вот как я делаю запрос.
@Multipart
@POST("installationdocument")
Call<Void> createNewDocument(@Header(AUTH_HEADER) String authorization, @Part ArrayList<MultipartBody.Part> images, @Part("document") RequestBody json);
И:
@Override
public void callRestApi(PuriRestApi restApi, RestApiJobService.ApiRequestor apiRequestor) {
MediaType JSON = MediaType.parse("application/json");
MediaType JPG = MediaType.parse("image/jpg");
ArrayList<MultipartBody.Part> imageParts = new ArrayList<>();
for (String imagePath : imagePaths) {
File image = new File(imagePath);
RequestBody imageBody = RequestBody.create(JPG, image);
imageParts.add(MultipartBody.Part.createFormData("images", image.getName(), imageBody));
}
RequestBody jsonPart = RequestBody.create(JSON, documentString);
apiRequestor.request(restApi.createNewDocument(authentication, imageParts, jsonPart), response -> {
if (response.isSuccessful()) {
if (imagePaths != null && imagePaths.length > 0) {
for (String imagePath : imagePaths) {
File image = new File(imagePath);
image.delete();
}
}
return true;
} else {
return false;
}
});
}
Возможно, создание большой переменной - это то, что вызывает эту ошибку. Поскольку переменная ArrayList<MultipartBody.Part> imageParts
будет содержать около 150 МБ данных изображения с 30 изображениями. Но кроме этого я понятия не имею, что может быть причиной этой ошибки.
Любая помощь действительно приветствуется.