Search code examples
androidwebviewtitaniumappcelerator

Android WebView abnormal large zoom level and font sizes on some devices


I have an older Android Titanium application that uses Titanium SDK 5.5.1 (I cannot use SDK 6+ because the code uses Ti.include). The app uses a WebView to display local CSS styled html content. Recently, some Android devices running Android 6+ have suddenly started displaying the WebView content using huge fonts that fill the screen with a few words. This happens on some devices but not others and I cannot replicate it on the device I use for testing (Samsung Galaxy S7 running Android 7.0) nor any of the emulators (either Genymotion or built-in Android SDK).

I have tried everything I can think of. I set the meta viewport using various options - currently it is as follows, per Android recommendations:

<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />

I tried adding width=device-width to content, but that did not make a difference and apparently it is inferred and not necessary when using initial-scale=1.0.

I also hard coded the font-size CSS property to a set pixel size in the page style header in both the and the the wrapper div class, still no luck.

body {font-size:13px;}
.contentClass {font-size:13px;}

I also tried changing the WebView scalesToFit property from false (the old setting) to true, but no difference. Nothing seems to work, the fonts remain huge on some devices.

The WebView creation code is as follows, nothing special:

var webView = Ti.UI.createWebView({
        top:0,
        html:htmlContent,
        width: Titanium.UI.FILL, //webview is added to main window which is the set to device screen width
        height: '100%',
        scalesPageToFit: true, //tried false as well
        enableZoomControls: false,
});

The app has many active users who are now complaining because of this. Since I cannot replicate the problem in my development environment, I am working in the dark. A few users who are experiencing this are helping me beta test a fix, but it is quite difficult to debug. Any insights would be much appreciated.


Solution

  • I figured out the reason for this problem and thought I'd share my solution.

    First, Android WebViews use the Chrome rendering agent and since v. 5.0 (Lollipop) this has been moved to the Chrome APK so it can be updated independently of the OS. At some point recently a new release of Chrome caused my WebView to stop working. You can learn more about this here: https://developer.chrome.com/multidevice/webview/overview

    I uncovered this by deactivating Chrome on my test phone. This has the effect of reverting Chrome to the device factory install version of Chrome which can be considerably older than the most recent one depending on the phone. In my case, the default Chrome version (56.x) worked fine, the newest version (60.0.3112.116) broke my WebView.

    The actual reason for the problem was an old setting I had in my Android manifest, namely android:anyDensity="false":

    <supports-screens android:anyDensity="false" android:largeScreens="true"
                    android:normalScreens="true" android:smallScreens="true"/> 
    

    The anyDensity setting tells Android whether the app supports any density screens. I set it to false a long time ago because this had the effect of automatically scaling my app for various screen sizes. Not a good approach, but it worked well for a long time. However, a recent Chrome release no longer handled this well causing the WebView to display hugely zoomed in and mis-sized, and be non-responsive to viewport settings etc. It also caused some other strange non-WebView behavior like View opacity not working.

    Removing the anyDensity setting or setting it to true (which is the default) solved the problem. Android recommends this always be set to true unless there's a good reason to set it to false like bitmap processing. And this should be done programmatically and not globally in the manifest. https://developer.android.com/guide/topics/manifest/supports-screens-element.html