【问题标题】:WebView targeting 29 not showing content面向 29 的 WebView 未显示内容
【发布时间】:2020-01-23 11:31:59
【问题描述】:

我有一个带有最新声明的应用:

compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'

defaultConfig {
    minSdkVersion 19
    targetSdkVersion 29
    ...

而且我在应用程序中几乎没有WebViews - 全尺寸ActivityFragment 版本以及一个固定尺寸的广告(比如说300x300dp,水平居中)View 放置在带有原生小部件的列表中.最后一个在目标更新后不再加载(只有这个,所有其他都在工作),但是当我在线更改(恢复)时:

    targetSdkVersion 28

它与更新前一样工作。此广告的整个 WebView 设置如下所示:

webView = findViewById(R.id.ad_banner_webview);
webView.setLayerType(Build.VERSION.SDK_INT <= 19 ?
            WebView.LAYER_TYPE_SOFTWARE : // on older devices non-fullactivity webview is blinking/glitching
            WebView.LAYER_TYPE_HARDWARE, null);
webView.setBackgroundColor(Color.TRANSPARENT);
final String userAgent = AppInfo.getInstance(webView.getContext()).getUserAgent();
webView.getSettings().setUserAgentString(userAgent);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setTextZoom(100);
webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new CustomWebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        if (!isDummy)
            webViewContainer.setTag(System.currentTimeMillis());
    }
});

//disabling long touch - text not selectable
webView.setOnLongClickListener(v -> true);
webView.setLongClickable(false);
webView.setHapticFeedbackEnabled(false);

请注意,在 API 19(支持的最低版本)上,webView 调用了 setLayerType(WebView.LAYER_TYPE_SOFTWARE) 并且始终在工作,无论定位如何...

问题很简单:这种行为的原因是什么以及如何解决这个问题?

我正在查看 DOCs 在目标更新后可能会改变我的应用行为的内容,但没有关于 WebView 的消息。我还发现了一些关于WebView - so-called Trichrome 渲染变化的隐藏信息,但仍然不知道它是否相关 - 我没有任何特殊的日志/输出有任何线索和问题来自5.0 到 10,在这些我使用 LAYER_TYPE_HARDWARE

【问题讨论】:

    标签: android webview android-10.0


    【解决方案1】:

    事实证明,这种加载内容的方式非常重要......我们在 WebView 中有 loadUrlloadDataloadDataWithBaseURL 方法,这三个方法都以非常不同的方式处理给定的输入数据

    在我的例子中,有问题的是loadData,代码类似于:

    <body style="margin: 0; padding: 0"><div class='banner-wrap'>        
    <iframe class='html5-iframe' src='https://example.com/html5/123.html#https://example-ads.com/deliver/ad.php?param=123__destination=https%3A%2F%2Fwww.anothersite.com%2F' width='300' height='300'>
    </iframe>    
    <a href='https://example.com/html5/123.html#https://example-ads.com/deliver/ad.php?param=123__destination=https%3A%2F%2Fwww.anothersite.com%2F' target='_blank'>
    </a>    
    </div></body>
    

    请注意,url 是 html 转义的(存在 %),但有一个例外:url 中的 #。 URL iframe 中存在此字符将不会加载内容...并且在定位 loadUrl 时,无论目标如何,都可以使用-#-url 进行操作。但我正在适应已经存在的广告分发系统,并且不会针对应用程序进行更改。我也认为操纵给定的 HTML 代码来提取 src url 不是正确的方法(系统可能有一天会升级)...

    我现在的解决方案是使用base64 并为WebView 设置相同的编码:

    String base64version = Base64.encodeToString(htmlData.getBytes(), Base64.DEFAULT);
    webView.loadData(base64version, "text/html; charset=UTF-8", "base64");
    

    【讨论】:

    • 非常感谢这个解决方案的人!我已经支持这件事很长时间了。
    • 所以你加载base64Version?这是怎么回事?我想您不想在 webView 中显示 base64 字符串?我试过了,结果是整个文本编码:S
    • HTML 数据使用 Base64 编码,但 webView.loadData( 方法在最后一个属性中确定 "base64"。很适合我
    【解决方案2】:

    我在更新版本 SDK 29 时遇到了同样的问题。我更改了适用于 SDK 版本 29 的代码

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        WebViewClientImpl webViewClient = new WebViewClientImpl(this);
        webView.setWebViewClient(webViewClient);
        webView.setWebChromeClient(new WebChromeClient());
        webView.loadDataWithBaseURL(null,html_content,"text/html","UTF-8",null);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-06
      • 2014-02-14
      • 2017-08-20
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 2012-02-27
      相关资源
      最近更新 更多