Android Webview cannot render the pdf sometimes and shows blank/white page instead

后端 未结 5 2013
感情败类
感情败类 2021-01-11 13:51
  • Open the pdf in the webview using google docs
  • Open the same pdf or different pdf again and again.
  • Sometimes it will show the blank/white page in the
相关标签:
5条回答
  • 2021-01-11 14:12

    You can reload the page until it displays the pdf in this way:

    public void onPageFinished(WebView view, String url) {
    if (view.getTitle().equals(""))
        view.reload();
    }
    
    0 讨论(0)
  • 2021-01-11 14:22

    Tested in multiple devices and working within API 29

    in Kotlin

     val webSettings: WebSettings = webview.settings
        webSettings.javaScriptEnabled = true
        webSettings.useWideViewPort = true
        webSettings.loadWithOverviewMode = true
        webSettings.domStorageEnabled = true
    
        webview.webViewClient = AppWebViewClients()
    // val TERM_CONDITION_URL = "http://docs.google.com/gview?embedded=true&url="
    //          + "YOUR_DOC_URL_HERE"
    
       bindind?.webview?.loadUrl(TERM_CONDITION_URL) 
    

    and here AppWebViewClients class

        class AppWebViewClients : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView, url: String?): Boolean {
            view.loadUrl(url)
            return true
        }
    
        override fun onPageFinished(view: WebView?, url: String?) {
            if (view?.contentHeight == 0)
                view?.reload();
            else {
                super.onPageFinished(view, url)
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-11 14:23

    After testing second PDF URL file, WebView seems like that can not load large PDF file.

    Reason:

    WebView display HTML. The fact that this works at all is by a hack- google will convert simple PDFs into HTML. It doesn't seem like they support anything that big. Even if they did, I would expect loading a large page PDF converted to HTML would be so large I highly doubt you'd be able to load it without going OOM. Use an appropriate PDF library, make a real PDF rendering view, and make sure not to render more of the PDF at a time than you need (or else you'll go OOM anyway). In other words, don't rely on hacky solutions you never should have relied on in the first place.

    Solution:

    You should try alternatives like PDF.js running locally in your device, instead of a service like Google Docs preview.(Or download PDF first to local file path)

    Put it in your assets folder and tweak the example:

    wv.loadUrl("file:///android_asset/web/viewer.html");
    

    Also, you can have Out Of Memory situations. An alternative to try is a native viewer like AndroidPdfViewer.

    0 讨论(0)
  • 2021-01-11 14:32

    We can solve the Problem in the two ways. 1. One is to use the Js.Pdf Plugin on the server end. It surely solve the problem but if we have multiple pdf's in the Fragment then it may cause the out of memory situations and app can crash. 2. Second option is we can recursively called the function to load webview. This will also cause the issue but with less frequency Below is the code:

    private void showPdf(final String imageString) {
    pdfView.invalidate();
    pdfView.getSettings().setJavaScriptEnabled(true);
    pdfView.getSettings().setSupportZoom(true);
    pdfView.loadUrl("http://docs.google.com/gview?embedded=true&url=" + imageString);
    pdfView.setWebViewClient(new WebViewClient() {
        boolean checkhasOnPageStarted = false;
    
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            checkhasOnPageStarted = true;
        }
    
        @Override
        public void onPageFinished(WebView view, String url) {
            if (checkhasOnPageStarted ) {
                pdfView.loadUrl(removePdfTopIcon);
            } else {
                showPdf(imageString);
            }
        }
    });
    }
    
    0 讨论(0)
  • 2021-01-11 14:33

    I was having the exact same issue and found that there was always a chance the WebView would not load on the first load attempt, especially if the pdf was on the larger side. The code I put together below works 100% of the time. From my beginner's understanding, it safely utilizes a separate thread to loop through and test the load status of the WebView, re-attempting a load of the view until successful. As this question was posted a year ago, I have generalized my solution to best benefit new viewers.

    public class WebViewActivity extends AppCompatActivity {
    
    String PDFView;
    WebView webView;
    String PDFBrowserView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Get the intended "PDFView"
        PDFView = getIntent().getExtras().get("PDFView").toString();
        //Have to manually encode (?) the url to display it
        try {
            PDFView = URLEncoder.encode(PDFView, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //Full display url
        PDFBrowserView = "https://docs.google.com/gview?embedded=true&url=" + PDFView;
    
        //Initialize a new "WebView" instance
        webView = new WebView(WebViewActivity.this);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setAllowFileAccessFromFileURLs(true);
        webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
        webView.getSettings().setBuiltInZoomControls(true);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setPluginState(WebSettings.PluginState.ON);
        webView.getSettings().setDomStorageEnabled(true);
        webView.getSettings().setLoadWithOverviewMode(true);
        webView.getSettings().setUseWideViewPort(true);
        //This handles callbacks (?)
        webView.setWebChromeClient(new WebChromeClient());
    
        //Call this to load page if page is blank with pdf url until page is not blank
        checkPageFinished();
    }
    
    public void checkPageFinished() {
        //If view is blank:
        if (webView.getContentHeight() == 0) {
    
            //Run off main thread to control delay
            webView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //Load url into the "WebView"
                    webView.loadUrl(PDFBrowserView);
                }
                //Set 1s delay to give the view a longer chance to load before 
                // setting the view (or more likely to display blank)
            }, 1000);
            //Set the view with the selected pdf
            setContentView(webView);
    
            webView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //If view is still blank:
                    if (webView.getContentHeight() == 0) {
                        //Loop until it works
                        checkPageFinished();
                    }
                }
                //Safely loop this function after 1.5s delay if page is not loaded
            }, 1500);
    
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题