OutOfMemoryError: Не удалось выделить 65548 байт для выделения с 3464 свободными байтами и 3 КБ до OOM при использовании модификации 2 и okhttp3 для загрузки - PullRequest
0 голосов
/ 30 января 2020

У меня возникают проблемы, когда я пытаюсь загрузить видеофайлы размером более 100 МБ, используя модификацию 2 в android. Когда я загружаю небольшие файлы, все работает нормально. В манифесте я установил android: largeHeap = "true" и android: hardwareAccelerated = "false", но это мне не помогло. Также я установил HttpLoggingInterceptor с уровнем NONE. Ниже приведен мой код.

try {
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Uploading...Please wait");
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.setCancelable(false);
        mProgressDialog.show();
        final String BASE_URL = serverUrl;

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.NONE);
        OkHttpClient client = new OkHttpClient.Builder().connectTimeout(3600, TimeUnit.SECONDS)
                .readTimeout(3600, TimeUnit.SECONDS).addInterceptor(logging).build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();

        UploadApiService service = retrofit.create(UploadApiService.class);
        File file = new File(uriRealPath);
        String typeF = null;
        String extension = MimeTypeMap.getFileExtensionFromUrl(uriRealPath);
        if (extension != null) {
            typeF = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
        }
        RequestBody requestBody = RequestBody.create(file,okhttp3.MediaType.parse(typeF));

        MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("video", file.getName(), requestBody);
        retrofit2.Call<Attachments> call = service.uploadVideo("bearer " + authtoken, fileToUpload);
        call.enqueue(new retrofit2.Callback<Attachments>() {

            @Override
            public void onResponse(retrofit2.Call<Attachments> call,
                                   retrofit2.Response<Attachments> response) {
                Attachments jjj = response.body();
                if (mProgressDialog != null) {
                    try {
                        addAttachedFile(response.body(), uriRealPath);
                        mProgressDialog.dismiss();
                    } catch (Exception e) { }
                }
            }

            @Override
            public void onFailure(retrofit2.Call<Attachments> call, Throwable t) {
                Log.e("Upload error:", t.getMessage());
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }

Ниже приведена трассировка стека ошибки.

I/art: Waiting for a blocking GC Alloc
I/art: Alloc partial concurrent mark sweep GC freed 106(4KB) AllocSpace objects, 2(415MB) LOS objects, 14% free, 96MB/112MB, paused 1.366ms total 156.987ms
I/art: WaitForGcToComplete blocked for 158.068ms for cause Background
I/art: WaitForGcToComplete blocked for 158.276ms for cause Alloc
    Starting a blocking GC Alloc
I/art: WaitForGcToComplete blocked for 158.750ms for cause Alloc
    Starting a blocking GC Alloc
I/Choreographer: Skipped 30 frames!  The application may be doing too much work on its main thread.
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #4
              Process: com.lss.loop, PID: 12021
              java.lang.RuntimeException: An error occurred while executing doInBackground()
                  at android.os.AsyncTask$3.done(AsyncTask.java:309)
                  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                  at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                  at java.lang.Thread.run(Thread.java:818)
               Caused by: java.lang.OutOfMemoryError: Failed to allocate a 65548 byte allocation with 3464 free bytes and 3KB until OOM
                  at com.android.okhttp.okio.Segment.<init>(Segment.java:62)
                  at com.android.okhttp.okio.SegmentPool.take(SegmentPool.java:46)
                  at com.android.okhttp.okio.Buffer.writableSegment(Buffer.java:1120)
                  at com.android.okhttp.okio.Buffer.write(Buffer.java:940)
                  at com.android.okhttp.okio.RealBufferedSink$1.write(RealBufferedSink.java:197)
                  at java.io.OutputStream.write(OutputStream.java:82)
                  at org.springframework.util.FileCopyUtils.copy(FileCopyUtils.java:144)
                  at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:74)
                  at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
                  at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:63)
                  at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:541)
                  at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:504)
                  at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:452)
                  at com.lss.loop.services.ServerAuthenticateService.uploadFileFromRealPath(ServerAuthenticateService.java:2845)
                  at com.lss.loop.view.AttachmentActivity$20.doInBackground(AttachmentActivity.java:1385)
                  at com.lss.loop.view.AttachmentActivity$20.doInBackground(AttachmentActivity.java:1376)
                  at android.os.AsyncTask$2.call(AsyncTask.java:295)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                  at java.lang.Thread.run(Thread.java:818) 
...