【问题标题】:Android Webview cannot render the pdf sometimes and shows blank/white page insteadAndroid Webview 有时无法呈现 pdf,而是显示空白/白页
【发布时间】:2019-09-13 17:09:42
【问题描述】:
  • 使用 google docs 在 webview 中打开 pdf
  • 一次又一次地打开相同的 pdf 或不同的 pdf。
  • 有时它会在 android 中显示空白/白色页面,直到我们再次刷新网页 1 或 2 次。

我已经在 pdf 上制作了示例。该项目的链接如下所示:

https://github.com/gopalawasthi123/PdfWebView

希望这会帮助你更好。

public void SetWebView(WebView webview,string externalUrl){
            webview.Tag = "webview";
            webview.Settings.JavaScriptEnabled = true;
            webview.Settings.SupportZoom ();
            webview.Settings.SetAppCacheEnabled(true);
            webview.Settings.DomStorageEnabled = true;
            webview.ZoomOut ();
            webview.ZoomIn ();
            webview.Settings.BuiltInZoomControls = true;
            webview.Settings.LoadWithOverviewMode = true;
            webview.Settings.UseWideViewPort = true;
            //webview.Settings.SetSupportZoom (true);
            webview.Settings.SetPluginState (WebSettings.PluginState.On);
            webview.Settings.GetPluginState ();
            if (externalUrl.StartsWith("http://") || externalUrl.StartsWith("https://"))
                webview.LoadUrl (externalUrl);
            webview.SetWebViewClient (new MonkeyWebViewClient (imgViewBack, imgViewForward, imgRefresh));
            webview.SetWebChromeClient (new WebChromeClient ());
        }

【问题讨论】:

  • 您好,感谢分享样例,您解决了这个问题吗?我找到了适合我的解决方案。如果需要,我会更新答案:)
  • 谢谢请更新。或者您也可以根据需要分享代码
  • 好的,我会分享解决方案:)
  • 你得到解决方案了吗?
  • @HariShankarS 我已经标记了正确的答案,您可以在下面对您有用的答案中尝试 Michelangelo Pucci 的答案

标签: java c# android xamarin.android android-webview


【解决方案1】:

我认为你应该这样做:

public void onPageFinished(WebView view, String url) {

    if (!view.getUrl().equals(url)) {
       view.loadUrl(url);
       return;
    }
}

【讨论】:

    【解决方案2】:

    在多个设备中测试并在 API 29 中工作

    在 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) 
    

    这里是AppWebViewClients

        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)
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我遇到了完全相同的问题,发现 WebView 在第一次加载尝试时总是有可能无法加载,尤其是当 pdf 文件较大时。我在下面整理的代码 100% 的时间都有效。根据我初学者的理解,它安全地利用单独的线程循环并测试 WebView 的加载状态,重新尝试加载视图直到成功。由于这个问题是在一年前发布的,我已经概括了我的解决方案,以最大程度地造福新观众。

      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);
      
              }
          }
      }
      

      【讨论】:

        【解决方案4】:

        我们可以通过两种方式解决问题。 1.一种是在服务器端使用Js.Pdf Plugin。它肯定可以解决问题,但是如果我们在片段中有多个 pdf,那么它可能会导致内存不足的情况 应用程序可能会崩溃。 2.第二种选择是我们可以递归调用函数来加载webview。这也会导致问题,但频率较低以下是代码:

        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);
                }
            }
        });
        }
        

        【讨论】:

          【解决方案5】:

          您可以重新加载页面,直到它以这种方式显示 pdf:

          public void onPageFinished(WebView view, String url) {
          if (view.getTitle().equals(""))
              view.reload();
          }
          

          【讨论】:

          • 这里不是获取标题,而是使用 if (view.getContentHeight() == 0) 条件比较您的条件,这将为您提供有关您的页面是否已加载的确切数据。
          【解决方案6】:

          在测试第二个 PDF URL 文件后,WebView 似乎无法加载大型 PDF 文件。

          原因:

          WebView 显示 HTML。这完全可行的事实是通过黑客 - 谷歌将简单的 PDF 转换为 HTML。他们似乎不支持那么大的东西。即使他们这样做了,我希望加载转换为 HTML 的大页面 PDF 会非常大,我非常怀疑您是否能够在不进入 OOM 的情况下加载它。使用适当的 PDF 库,制作真正的 PDF 渲染视图,并确保一次渲染的 PDF 不会超出您的需要(否则您无论如何都会去 OOM)。换句话说,不要依赖一开始就不应该依赖的 hacky 解决方案。

          解决方案:

          您应该尝试在您的设备中本地运行 PDF.js 等替代方案,而不是使用 Google 文档预览等服务。(或先将 PDF 下载到本地文件路径)

          将其放入您的资产文件夹并调整示例:

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

          此外,您可能会遇到内存不足的情况。尝试的替代方法是使用本地查看器,例如 AndroidPdfViewer

          【讨论】:

          • 我已经尝试了您的两种解决方案。但是如果您打开该 pdf 9 到 10 次页面将变为空白/白色,这些解决方案对我不起作用。您也可以将 url 更改为adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/…
          • @GopalAwasthi 嗨,测试新的url后,发现问题也存在。以前的解决方案可能无法完全解决。这是另一个原因。我已经更新了答案。
          猜你喜欢
          • 2012-12-27
          • 1970-01-01
          • 1970-01-01
          • 2014-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多