I have an app with this up-to-date declaration:
compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
defaultConfig {
minSdkVersion 19
targetSdkVersion 29
...
And also I have few WebView
s in app - full sized Activity
, Fragment
version and also an ad which is fixed size (lets say 300x300dp, centered horizontally) View
placed on list with native widgets. This last one is not loading anymore after target update (only this one, all other are working), but when I change (revert) just this on line:
targetSdkVersion 28
it is working as before update. Whole WebView
setting for this ad looks like this:
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);
Note that on API 19 (lowest supported) webView
has setLayerType(WebView.LAYER_TYPE_SOFTWARE)
called and is working always, no matter of targeting...
Question is simple: what is the reason of this behavior and how to fix this?
I was looking in 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, but still don't have idea is it related - I don't have any special log/output with any clue and issue is present from 5.0 to 10, on these I'm using LAYER_TYPE_HARDWARE
turning out that way of loading content matters a lot... we have loadUrl
, loadData
and loadDataWithBaseURL
methods in WebView
and all three are treating given input data in a very different ways
in my case problematic was loadData
with code similar to this:
<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>
note that url is html escaped (% present), but with one exception: the # in url. with this character present in URL iframe won't load content... and was loading when targeting <=28. when using loadUrl
giving this with-#-url everything works fine no matter of target. but I'm fitting into already exisiting ad distribution system and it won't be changed for app. also I think that manipulating given HTML code to extract src
url isn't a proper way (system may be upgraded somehow someday)...
my solution for now is to use base64
and set same encoding for WebView
:
String base64version = Base64.encodeToString(htmlData.getBytes(), Base64.DEFAULT);
webView.loadData(base64version, "text/html; charset=UTF-8", "base64");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With