针对 29 的 WebView 不显示内容
WebView targeting 29 not showing content
我有一个包含最新声明的应用程序:
compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
...
而且我在应用程序中也有几个 WebView
- 全尺寸 Activity
、Fragment
版本和固定尺寸的广告(比如 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 what may changed my app behavior after target update, but there is no word about WebView
. Also I've found some hidden info about changes in rendering by WebView
- so-called Trichrome,但仍然不知道它是否相关 - 我没有任何特殊的 log/output 有任何线索和问题存在于 5.0 到 10,在这些我使用 LAYER_TYPE_HARDWARE
事实证明,加载内容的方式很重要...我们在 WebView
中有 loadUrl
、loadData
和 loadDataWithBaseURL
方法,所有这三个方法都处理给定以非常不同的方式输入数据
在我的案例中,问题是 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 将不会加载内容...并且在目标 <=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");
I had the same issue while updating version SDK 29. I change my code it is working for SDK version 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);
我有一个包含最新声明的应用程序:
compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
...
而且我在应用程序中也有几个 WebView
- 全尺寸 Activity
、Fragment
版本和固定尺寸的广告(比如 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 what may changed my app behavior after target update, but there is no word about WebView
. Also I've found some hidden info about changes in rendering by WebView
- so-called Trichrome,但仍然不知道它是否相关 - 我没有任何特殊的 log/output 有任何线索和问题存在于 5.0 到 10,在这些我使用 LAYER_TYPE_HARDWARE
事实证明,加载内容的方式很重要...我们在 WebView
中有 loadUrl
、loadData
和 loadDataWithBaseURL
方法,所有这三个方法都处理给定以非常不同的方式输入数据
在我的案例中,问题是 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 将不会加载内容...并且在目标 <=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");
I had the same issue while updating version SDK 29. I change my code it is working for SDK version 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);