使用Retrofit(Android)上传大型视频文件时出现OutOfMemoryError

时间:2018-09-11 07:22:55

标签: android upload retrofit

对不起,我的英语。我尝试在服务器上上传大型视频文件,此文件超过50 mb。当我上传小文件时,一切正常。我在清单中设置了android:largeHeap="true"android:hardwareAccelerated="false"并没有帮助我。下面是我的代码:

接口

@Multipart
@POST("/api/upload")
Observable<UploadVideoResponse> uploadVideo(@Header("Authorization") String userToken,
                                            @Part MultipartBody.Part video);

方法返回文件:

public static MultipartBody.Part getMultipartVideoBody(String pathVideo) {
    try {
        File videoFile = getFile(pathVideo);
        RequestBody videoBody = RequestBody.create(MediaType.parse("video/*"), videoFile);
        String fileName = videoFile.getName();
        return MultipartBody.Part.createFormData("video", fileName, videoBody);
    }catch (Exception e){
        Log.e("File ", e.getMessage());
        return null;
    }
}

在服务器上上传方法

new DefaultApi().uploadVideo(
                Utils.getHeaderToken(),
                Utils.getMultipartVideoBody(pathVideo)
        ).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(videoView::showLoading)
                .doOnTerminate(videoView::hideLoading)
                .subscribe(data -> {
                            videoView.setData(data);
                        }
                        , throwable -> {

                        }
                );
    }

错误:

  

Throwing OutOfMemoryError“未能分配100390006字节   分配16777216个可用字节,直到OOM达到92MB”

完整的堆栈跟踪

  

09-11 03:53:00.571 6724-6976 / des.brain.ga E / art:投掷   OutOfMemoryError“无法使用以下命令分配100390006字节分配   16777216可用字节和92MB直到OOM“ 09-11 03:53:00.573   6724-6976 / des.brain.ga E / Android运行时:致命异常:   RxIoScheduler-3       流程:des.brain.ga,PID:6724       java.lang.IllegalStateException:在Scheduler.Worker线程上引发致命异常。           在rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59)           在java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:422)           在java.util.concurrent.FutureTask.run(FutureTask.java:237)           在java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 201(ScheduledThreadPoolExecutor.java:152)           在java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)           在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)           在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587)           在java.lang.Thread.run(Thread.java:818)        由以下原因引起:java.lang.OutOfMemoryError:无法分配100390006字节分配,其中包含16777216可用字节和92MB,直到OOM           在java.lang.String。(String.java:332)           在java.lang.String。(String.java:371)           在okio.Buffer.readString(Buffer.java:620)           在okio.Buffer.readString(Buffer.java:603)           在okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:199)           在des.brain.ga.api.base.LoggingInterceptor.intercept(LoggingInterceptor.java:31)           在okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)           在okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)           在okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)           在okhttp3.RealCall.execute(RealCall.java:77)           在retrofit2.OkHttpCall.execute(OkHttpCall.java:180)           在retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:40)           在retrofit2.adapter.rxjava.CallExecuteOnSubscribe.call(CallExecuteOnSubscribe.java:24)           在retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:36)           在retrofit2.adapter.rxjava.BodyOnSubscribe.call(BodyOnSubscribe.java:28)           在rx.Observable.unsafeSubscribe(Observable.java:10256)           在rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)           在rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)           在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)           在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)           在rx.Observable.unsafeSubscribe(Observable.java:10256)           在rx.internal.operators.OperatorSubscribeOn $ SubscribeOnSubscriber.call(OperatorSubscribeOn.java:100)           在rx.internal.schedulers.CachedThreadScheduler $ EventLoopWorker $ 1.call(CachedThreadScheduler.java:230)           在rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)           在java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:422)           在java.util.concurrent.FutureTask.run(FutureTask.java:237)           在java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 201(ScheduledThreadPoolExecutor.java:152)           在java.util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)           在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)           在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587)           在java.lang.Thread.run(Thread.java:818)09-11 03:53:02.159 6724-6724 / des.brain.ga E / WindowManager:android.view.WindowLeaked:   活动des.brain.ga.ui.main.HomeActivity已泄漏窗口   com.android.internal.policy.impl.PhoneWindow $ DecorView {2ccb16a1   V.ED .... R ..... ID 0,0-144,144},最初是在此处添加的           在android.view.ViewRootImpl。(ViewRootImpl.java:363)           在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)           在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)           在android.app.Dialog.show(Dialog.java:298)           在com.kaopiz.kprogresshud.KProgressHUD.show(KProgressHUD.java:233)           在des.brain.ga.ui.video.UploadVideoFragment.showLoading(UploadVideoFragment.java:150)           在des.brain.ga.ui.video.VideoPresenter $$ Lambda $ 4.call(来源不明)           在rx.internal.operators.OperatorDoOnSubscribe.call(OperatorDoOnSubscribe.java:40)           在rx.internal.operators.OperatorDoOnSubscribe.call(OperatorDoOnSubscribe.java:27)           在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:44)           在rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)           在rx.Observable.unsafeSubscribe(Observable.java:10256)           在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)           在rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)           在rx.Observable.subscribe(Observable.java:10352)           在rx.Observable.subscribe(Observable.java:10319)           在rx.Observable.subscribe(Observable.java:10159)           在des.brain.ga.ui.video.VideoPresenter.uploadVideo(VideoPresenter.java:65)           在des.brain.ga.ui.video.UploadVideoFragment.lambda $ uploadVideo $ 0 $ UploadVideoFragment(UploadVideoFragment.java:127)           在des.brain.ga.ui.video.UploadVideoFragment $$ Lambda $ 0.onClick(未知   资源)           在com.afollestad.materialdialogs.MaterialDialog.onClick(MaterialDialog.java:410)           在android.view.View.performClick(View.java:4756)           在android.view.View $ PerformClick.run(View.java:19749)           在android.os.Handler.handleCallback(Handler.java:739)           在android.os.Handler.dispatchMessage(Handler.java:95)           在android.os.Looper.loop(Looper.java:135)           在android.app.ActivityThread.main(ActivityThread.java:5221)           在java.lang.reflect.Method.invoke(本机方法)           在java.lang.reflect.Method.invoke(Method.java:372)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:899)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

LoggingInterceptor

public final class LoggingInterceptor implements Interceptor {

    private final Interceptor mLoggingInterceptor;

    private LoggingInterceptor() {
        mLoggingInterceptor = new HttpLoggingInterceptor()
                //.setLogLevel(RestAdapter.LogLevel.FULL)
                .setLevel(BuildConfig.DEBUG ? Level.BODY : Level.NONE);
    }

    @NonNull
    public static Interceptor create() {
        return new LoggingInterceptor();
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        return mLoggingInterceptor.intercept(chain);
    }

}

我这样使用LoggingInterceptor

return new OkHttpClient.Builder()
                .connectTimeout(300, TimeUnit.SECONDS)
                .addInterceptor(LoggingInterceptor.create())
                .addInterceptor(logging)
                .build();

1 个答案:

答案 0 :(得分:2)

使用翻新版上传大型视频时,我遇到了同样的错误,但是 删除
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
或设置为NONE 为我工作。