SKLn-Rad / Xam.Plugin.Webview

Xamarin Plugin for a HybridWebView in PCL projects.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Not loading StringData

IeuanWalker opened this issue · comments

Warning - This is rather strange.

We have been using this plugin for a few months now without an issue. Suddenly the page isn't getting loaded, even on an APK's that was generated months ago.

Plus its working on selected Android device.

<StackLayout Grid.Row="1"
             HorizontalOptions="FillAndExpand"
             VerticalOptions="FillAndExpand">
    <abstractions:FormsWebView x:Name="WebView"
                               ContentType="StringData"
                               Source="{Binding IshareWebViewSource}" />
</StackLayout>

Then in tha page init i have this -

 WebView.AddLocalCallback("invokeCSharp", _viewModel.IshareInvokeCSharp);

Then in the viewmodel i have this -

public void IshareInvokeCSharp(string obj)
{
    string[] eastNorth = obj.Split(',');

    UserSelectedNorthing = double.Parse(eastNorth[0]);
    UserSelectedEasting = double.Parse(eastNorth[1]);
}

And here is the HTML string that I bind to the WebView -

<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' style='height:100%'>

<head>
    <title>iShare - Lite</title>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <link href='https://ishare.cardiff.gov.uk/css/cc/Map.css' rel='stylesheet' type='text/css' />
    <link href='https://ishare.cardiff.gov.uk/css/Map_base.css' rel='stylesheet' type='text/css' />
    <link href='https://ishare.cardiff.gov.uk/css/atMyPages.css' rel='stylesheet' type='text/css' />
    <link href='https://ishare.cardiff.gov.uk/css/style.css' rel='stylesheet' type='text/css' />
    <link href='https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' rel='stylesheet' integrity='sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN'
        crossorigin='anonymous' />
</head>

<body style='font-size: 75.0%; Height: 100%; Margin: 0 auto'>
    <div id='atMap' style='height: 100%; Width: 100%'>
        <div id='atInitialLoader' style='border:1px solid #CCC;padding:5px;margin:125px auto auto;text-align:center;width:75px;font-family:Helvetica;'>Loading it...</div>
    </div>
    <script type='text/javascript' src='https://ishare.cardiff.gov.uk/FileIncluderJS.aspx'></script>
    <script type='text/JavaScript' src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
    <script type='text/JavaScript' src='https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.min.js'></script>
    <script>
        function remove_map_listener() {
            // Remove keylisteners                                  
            this.astun.mapWrapper.map.controls.forEach(function (ctrl) {
                if (ctrl.displayClass === 'olControlKeyboardDefaults') {
                    ctrl.deactivate()
                }
            });

            // Get latitude longitude
            var clickCtrl = new OpenLayers.Control.Click({ 'double': false, pixelTolerance: 1 }, {
                click: function (evt) {
                    var clickPixel = evt.xy;
                    var clickLonLat = this.map.getLonLatFromPixel(clickPixel);

                    clickLonLatstring = clickLonLat.toString().split(',');
                    var easting = clickLonLatstring[0].replace('lon=', '');
                    var northing = clickLonLatstring[1].replace('lat=', '');
                    // send nothing to c#
                    invokeCSharp(northing + ',' + easting);
                }
            });
            this.astun.mapWrapper.map.addControl(clickCtrl);
            clickCtrl.activate();
        }
        function invokeCSharp(eastNorth) {
            alert(eastNorth);
            invokeCSharpAction(eastNorth);
        }
    </script>
    <script type='text/javascript'>
        Event.observe(window, 'load', function () {
            Astun.JS.IncludeJS('lite', function () {
                $('atMap').map = new Astun.JS.Map('atMap', {
                    layers: 'cardiffcounty',
                    view: { easting: 318162, northing: 176573, zoom: 3000 },
                    mapsource: 'Cardiff_Live/AllMaps'
                });
                jQuery('#atMap').bind('dataLayersLoaded', function ($evt, mapSource, type) {
                    // The map should now be loaded...                                                                       
                    remove_map_listener();
                });
            });
        });
    </script>
</body>

</html>

I can confirm the same problem. Oddly, I'm only seeing it on my device. The emulator loads an HTML string just fine.

** It can be reproduced using this project's sample project code which loads a simple html string. **

This is the sample I'm referring to: https://github.com/SKLn-Rad/Xam.Plugin.Webview/blob/master/SampleApp/SampleApp/Samples/StringDataSample.xaml.cs

To reproduce:

  1. Build the android sample project and run on a device
  2. Click on the string sample

The web view will crash and not load the html.

The relevant code is here:

https://github.com/SKLn-Rad/Xam.Plugin.Webview/blob/master/Xam.Plugin.WebView.Droid/FormsWebViewRenderer.cs#L208

which calls the android webview's LoadDataWithBaseURL method. It looks like the method is getting the right parameters. Can anyone else confirm the problem or have suggestions?

A lot of discussion of LoadDataWithBaseUrl here: https://bugs.chromium.org/p/chromium/issues/detail?id=669885&q=LoadDataWithBaseUrl&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

Apparently the behavior of the function isn't very well understood. This statement starts a very long thread which is hard to follow:

The documentation for loadDataWithBaseUrl isn't very specific about what the exact effects of changing the base url and history url actually are.

I thought maybe the problem is that the right base url isn't being passed in to facilitate loading a string.

In the test project that is part of this project, in LoadFromString() I've tried the following:

Control.LoadDataWithBaseURL("", MimeType, EncodingType, HistoryUri); // <-- Empty string
Control.LoadDataWithBaseURL("file:///android_asset", Element.Source, MimeType, EncodingType, HistoryUri); // <-- What the method is currently defaulting to
Control.LoadDataWithBaseURL(null, Element.Source, MimeType, EncodingType, HistoryUri); // <-- What the android docs suggest defaults to "about:blank" -- but unclear what the consequences of that would be

It would seem like:

Control.LoadData(Element.Source, MimeType, EncodingType);

could also be a candidate. Tried it and it has the same problem.

Basically all these attempts at loading a simple html string are hanging up the webview on android 7.1 on an actual device.

I have the same problem, and it seems that it start to occurs when Chrome was updated from 64.0.3282.137 to 66.0.3359.158, but I haven't found any fixes yet, it's a very big pb for my project...

@Nico04 the only way I managed to get around it is by creating an HTML page and using the JS calls to make changes after its loaded

@IeuanWalker What do you mean by "creating a HTML" ?
In my project, I have an embedded html that I load with LoadDataWithBaseURL.
Thank you for your quick answer anyway :)

I've spent my day on this matter as this component is very important in my project, and I found a fix.
I've forked the project so everyone can see my solution, and hopefully @SKLn-Rad will include my fix in the next release.

https://github.com/Nico04/Xam.Plugin.Webview/commit/223983d4d4da0208f3979a9779652bcdfea341e6

@Nico04 Great, I meant create a HTML file rather than have a HTML string. After this situation, I don't trust using HTML strings

Closed no longer an issue