Android Webview有时无法呈现pdf,而是显示空白页/白页

时间:2019-04-24 11:53:49

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

  • 使用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 ());
        }

5 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

我们可以通过两种方式解决问题。  1.一种是在服务器端使用Js.Pdf插件。它肯定可以解决问题,但是如果我们在Fragment中有多个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);
        }
    }
});
}

答案 2 :(得分:0)

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

原因:

WebView显示HTML。完全可以通过Google破解的事实将简单的PDF转换为HTML。他们似乎并没有支持那么大的东西。即使他们这样做了,我也希望加载转换成HTML的大页面PDF会是如此之大,我非常怀疑您是否能够在不进行OOM的情况下加载它。使用适当的PDF库,创建真实的PDF渲染视图,并确保一次不渲染超出所需数量的PDF(否则,无论如何都会进行OOM操作)。换句话说,不要依赖本来就不应该依赖的hacky解决方案。

解决方案:

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

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

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

此外,您可能会遇到内存不足的情况。可以尝试的替代方法是像AndroidPdfViewer这样的本机查看器。

答案 3 :(得分:0)

我遇到了完全相同的问题,发现总是有机会在第一次尝试加载时不加载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 :(得分:0)

已在多种设备中测试并在API 29中运行

在科特林

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