【问题标题】:NetworkOnmainThreadException android+RxjavaNetworkOnmainThreadException android+Rxjava
【发布时间】:2021-03-21 21:58:58
【问题描述】:

我有将字节流写入文件并返回文件的代码 但我在将输入流写入文件时遇到 networkonmainthreadexception

accessTokenValidationWithResponseBodyForPDF(LinkApi.downloadFile(fileUrl))
                .flatMap(new Function<ResponseBody, ObservableSource<File>>() {
                    @Override
                    public ObservableSource<File> apply(@io.reactivex.annotations.NonNull ResponseBody responseBody) throws Exception {
                        return Observable.just(writeResponseBodyToDisk(responseBody))
                                .onErrorReturn(new Function<Throwable, File>() {
                                    @Override
                                    public File apply(@io.reactivex.annotations.NonNull Throwable throwable) throws Exception {
                                        return new File(AppConstants.not_valid);
                                    }
                                });
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DisposableObserver<File>() {
                    @Override
                    public void onNext(@NotNull File resultObject) {
                        try {
                            hideProgress();
                            if (resultObject.getPath().equals(AppConstants.not_valid)) {

                                showAlertDialog(getString(R.string.something_went_wrong), true);

                            } else {

                                File pdfFile = (File) resultObject;
                                downloadedFile = pdfFile;
                                if (pdfFile != null) {
                                    displayPdf(pdfFile);
                                }

                            }
                        } catch (Exception e) {
                        }

                    }

                    @Override
                    public void onError(Throwable throwable) {
                        hideProgress();
                        
                    }

                    @Override
                    public void onComplete() {

                    }
                });
     private File writeResponseBodyToDisk(ResponseBody body) {

        
        String extStorageDirectory = getApplicationContext().getFilesDir().toString();

        File folder = new File(extStorageDirectory, ".Link");
        if (!folder.exists())
            folder.mkdir();

        SecureRandom secureRandom = new SecureRandom();
        int random = secureRandom.nextInt();

        File futureStudioIconFile = new File(extStorageDirectory + File.separator + ".Link" + File.separator + "link" + random + ".pdf");

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            byte[] fileReader = new byte[4096];

            long fileSize = body.contentLength();
            long fileSizeDownloaded = 0;

            inputStream = body.byteStream();
            outputStream = new FileOutputStream(futureStudioIconFile);

            while (true) {
                int read = inputStream.read(fileReader);//going to exception with networkonmainthreadexception

                if (read == -1) {
                    break;
                }

                outputStream.write(fileReader, 0, read);

                fileSizeDownloaded += read;

            }

//                outputStream.flush();

        } catch (Exception e) {

            Log.i("PDF", e.getMessage());
        } finally {
            safeClose(inputStream);
            safeClose(outputStream);
        }


        return futureStudioIconFile;

    }

【问题讨论】:

    标签: android rx-java2


    【解决方案1】:

    发生这种情况是因为您调用 writeResponseBodyToDisk 然后将其结果转换为 Observable。您必须使方法调用本身发生在后台线程上,例如通过

    Observable.fromCallable(() -> writeResponseBodyToDisk(responseBody))
    .subscribeOn(Schedulers.io())
    .onErrorReturn(...)
    

    请注意,在您的原始代码中包含.subscribeOn(Schedulers.io()) 不会到达flatMap,因为该函数在accessTokenValidationWithResponseBodyForPDF 的发射器线程上运行。你必须把subscribeOns 放在离作品很近的地方,并且经常在很多地方重复很多次。

    【讨论】:

    • 谢谢它的工作..真的帮助你的解释,因为我正在学习 rxjava
    • 我改变如下是正确的吗? return Observable.fromCallable(()->writeResponseBodyToDisk(responseBody)) .subscribeOn(Schedulers.io()) .onErrorReturn({...}) }); }
    猜你喜欢
    • 2018-12-15
    • 2017-09-15
    • 2016-03-24
    • 2017-10-15
    • 2018-09-11
    • 2021-03-25
    • 1970-01-01
    • 2016-12-11
    • 2012-11-16
    相关资源
    最近更新 更多