java - onComplete() 在成功下载 pdf (Rxjava) 后永远不会被调用,但在使用 AsyncTask 时可以工作

标签 java android pdf android-asynctask rx-java

我正在尝试使用 Rxjava2 的 onNext() 从 url 下载 pdf 文件。下载文件并将其存储在文件夹中后,我在 oncomplete() 中编写了代码逻辑,以通过 Intent 打开 pdfview 向用户显示 pdf。但 onComplete() 永远不会被调用。也使用断点来检查,但编译器不会执行 onComplete()。

主要 Activity :

        home_quarantine_guidelines.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                 observable = Observable.just
                        ("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf");

                observable.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new DisposableObserver<String>() {
                            @Override
                            public void onNext(String s) {
                                //customProgressDialog.show();

                                String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
                                File folder = new File(extStorageDirectory, "Intelehealth_COVID_PDF");
                                folder.mkdir();

                                File pdfFile = new File(folder, "dummy.pdf");

                                try{
                                    pdfFile.createNewFile();
                                }catch (IOException e){
                                    e.printStackTrace();
                                }

                                FileDownloader.downloadFile(s, pdfFile);

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {
                                customProgressDialog.dismiss();

                                File pdfFile = new File
                                        (Environment.getExternalStorageDirectory()
                                                + "/Intelehealth_COVID_PDF/" + "dummy.pdf");

                    Uri path = FileProvider.getUriForFile
                            (context, context.getApplicationContext().getPackageName()
                                    + ".provider", pdfFile);
                    Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
                    pdfIntent.setDataAndType(path, "application/pdf");
                    pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    pdfIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    pdfIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

                    try{
                        startActivity(pdfIntent);
                    }catch(ActivityNotFoundException e){
                        Toast.makeText(HomeActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
                    }

                            }
                        });

//                File pdfFile_downloaded = new File(Environment.getExternalStorageDirectory() + "/Intelehealth_COVID_PDF/" + "dummy.pdf");
//
//                if(pdfFile_downloaded.exists())
//                {
//                    File pdfFile = new File(Environment.getExternalStorageDirectory() + "/Intelehealth_COVID_PDF/" + "dummy.pdf");  // -> filename = maven.pdf
//                    //Uri path = Uri.fromFile(pdfFile);
//                    Uri path = FileProvider.getUriForFile
//                            (context, context.getApplicationContext().getPackageName()
//                                    + ".provider", pdfFile);
//                    Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
//                    pdfIntent.setDataAndType(path, "application/pdf");
//                    pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//                    pdfIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//                    pdfIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
//
//                    try{
//                        startActivity(pdfIntent);
//                    }catch(ActivityNotFoundException e){
//                        Toast.makeText(HomeActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
//                    }
//                }
//                else
//                {
//                    customProgressDialog.show();
//                    new DownloadFile().execute("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", "dummy.pdf");
//                }




            }
        });

文件下载.class:

public class FileDownloader extends FileProvider {
    private static final int  MEGABYTE = 1024 * 1024;

    public static void downloadFile(String fileUrl, File directory){
        try {

            URL url = new URL(fileUrl);
            HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
           // urlConnection.setRequestMethod("GET");
          //  urlConnection.setDoOutput(true);
            urlConnection.connect();

            InputStream inputStream = urlConnection.getInputStream();
            FileOutputStream fileOutputStream = new FileOutputStream(directory);
            int totalSize = urlConnection.getContentLength();

            byte[] buffer = new byte[MEGABYTE];
            int bufferLength = 0;
            while((bufferLength = inputStream.read(buffer)) > 0){
                fileOutputStream.write(buffer, 0, bufferLength);
            }
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

EDIT: When I use AsyncTask, the code executes correctly. But why does it not execute/work using RxJava2 ?

最佳答案

根据@EpicPandaForce在评论中给出的提示,我找到了这个问题。我使用 Rxjava 的 create 运算符来发出单个项目。因此它永远不会到达 onComplete()。根据给定的提示并引用文档,我意识到我必须使用 Single.fromCallable() 因为我想发出单个线程。

代码:

  Single.fromCallable(() ->
            {
                String s = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
                String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
                File folder = new File(extStorageDirectory, "Intelehealth_COVID_PDF");
                folder.mkdir();

                File pdfFile = new File(folder, "dummy.pdf");

                try{
                    pdfFile.createNewFile();

                }catch (IOException e){
                    e.printStackTrace();
                }

                FileDownloader.downloadFile(s, pdfFile);


                return s;
            })
                    .subscribeOn(Schedulers.io())
                    .subscribe(new SingleObserver<String>() {
                        @Override
                        public void onSubscribe(Disposable d) {

                        }

                        @Override
                        public void onSuccess(String s) {
                            File pdfFile = new File
                                    (Environment.getExternalStorageDirectory()
                                            + "/Intelehealth_COVID_PDF/" + "dummy.pdf");

                            Uri path = FileProvider.getUriForFile
                                    (context, context.getApplicationContext().getPackageName()
                                            + ".provider", pdfFile);
                            Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
                            pdfIntent.setDataAndType(path, "application/pdf");
                            pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                            pdfIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            pdfIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

                            try{
                                startActivity(pdfIntent);
                            }catch(ActivityNotFoundException e){
                                Toast.makeText(HomeActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
                            }
                        }

                        @Override
                        public void onError(Throwable e) {

                        }
                    });

关于java - onComplete() 在成功下载 pdf (Rxjava) 后永远不会被调用,但在使用 AsyncTask 时可以工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60761351/

相关文章:

java - 在 TextView 上显示字符串不起作用

java - Android ime actionGo 在某些设备上不工作

android - mailto:在 android 中不支持正文中带有空格的链接

java - 如何在java web应用程序中的pdf报告中绘制图表

c# - 使用 XMLWorker 将 HTML 解析为 PDF 时设置行间距 - ITextSharp C#

java - 在运行作为 JAR 存档分发的项目时加载图像等资源

java - 如何运行 Atmosphere 示例

pdf - JavaFX:在 WebView 中显示 PDF

java - 为私有(private)静态内部类注入(inject)bean

java - 如何在类似于 GridView 的 GridLayout 中获取选定的子项