android - 面向 29 的 WebView 未显示内容

标签 android webview android-10.0

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

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

defaultConfig {
    minSdkVersion 19
    targetSdkVersion 29
    ...

而且我也很少WebView应用程序中的 s - 全尺寸 Activity , Fragment版本和一个固定尺寸的广告(比如说 300x300dp,水平居中)View与 native 小部件一起放置在列表中。最后一个在目标更新后不再加载(只有这个,所有其他都在工作),但是当我在线更改(恢复)时:
    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(支持的最低版本)webViewsetLayerType(WebView.LAYER_TYPE_SOFTWARE)打电话并且一直在工作,无论目标...

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

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

最佳答案

事实证明这种加载内容的方式很重要...我们有 loadUrl , loadDataloadDataWithBaseURL WebView 中的方法并且这三个都以非常不同的方式处理给定的输入数据
在我的情况下,有问题的是 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 转义的(% 存在),但有一个异常(exception): # 在网址中。 URL iframe 中存在此字符将不会加载内容...并且在定位 <=28 时正在加载。使用 loadUrl 时无论目标是什么,使用-#-url 都可以正常工作。但我正在适应已经存在的广告分发系统,并且不会针对应用程序进行更改。我也认为操纵给定的 HTML 代码来提取 src url 不是正确的方法(系统可能有一天会以某种方式升级)...
我现在的解决方案是使用 base64并为 WebView 设置相同的编码:
String base64version = Base64.encodeToString(htmlData.getBytes(), Base64.DEFAULT);
webView.loadData(base64version, "text/html; charset=UTF-8", "base64");

关于android - 面向 29 的 WebView 未显示内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58061708/

相关文章:

java - 从 Android 设备访问 SQL DB 时,我的 httpEntity 返回 null,任何人都可以告诉我这是为什么吗?

android - Android studio如何知道有多少人连接到Firebase?

cocoa - 通过 stringByEvaluatingJavaScriptFromString 将文本从文件传递到 webview :

安卓 v2.2-2.3.5 : WebView : loadDataWithBaseURL : will only load page once

java - Api 29 (Android Q) 外部应用程序目录中的 SQLiteOpenHelper

android - Android 30 的来源在哪里

android - 当 Android Q 中的 minifyEnabled = true 时,具有数据绑定(bind)的 LiveData 不起作用

android - 如何获取 ScrollView 的滚动量

android - Youtube iframe 播放器不会在 android 4.x WebView 中显示视频

android - 与 kotlin 异步运行代码的最佳方式