Xamarin.Forms HybridWebView在API 23中什么都不做

时间:2017-09-11 11:29:52

标签: android xamarin.forms xamarin.android hybrid-mobile-app

在Xamarin.Forms中我有一个在API 19 android中运行良好的HybridWebView。但是不能在API 23中工作。我没有为其他人测试。我的Xamarin和目标API是最后一个并更新。

我的问题是为什么这不适用于API 23?

这是我的Hybridwebview

namespace MyNameSpace.CustomRenderer
{
public class MyHybridWebView : View
{
    public bool Loaded { get; set; }
    public bool TimeOut { get; set; }

    public bool Terminate { get; set; }

    public void TerminateLoading()
    {
        Terminate = true;
    }

    public int ContentHeight { get; set; }
    public double Progress { get; set; }

    public void OpenLinkExternally(string url)
    {
        Device.OpenUri(new Uri(url));
    }


    Action<string> action;

    public static readonly BindableProperty UriProperty = BindableProperty.Create(
        propertyName: "Uri",
        returnType: typeof(string),
        declaringType: typeof(MyHybridWebView),
        defaultValue: default(string));

    public static readonly BindableProperty LoadHtmlCodeProperty = BindableProperty.Create(
        propertyName: "LoadHtmlCode",
        returnType: typeof(string),
        declaringType: typeof(MyHybridWebView),
        defaultValue: default(string));

    public string Uri
    {
        get { return (string)GetValue(UriProperty); }
        set { SetValue(UriProperty, value); }
    }
    public string LoadHtmlCode
    {
        get { return (string)GetValue(LoadHtmlCodeProperty); }
        set { SetValue(LoadHtmlCodeProperty, value); }
    }

    public void RegisterAction(Action<string> callback)
    {
        action = callback;
    }

    public void Cleanup()
    {
        action = null;
    }

    public void InvokeAction(string data)
    {
        if (action == null || data == null)
        {
            return;
        }
        action.Invoke(data);
    }
}

}

这是我的android渲染器:

  [assembly: ExportRenderer(typeof(MyHybridWebView), 
   typeof(MyHybridWebViewRenderer))]

namespace MyNameSpace.Droid.Renderers
{
public class MyHybridWebViewRenderer : ViewRenderer<MyHybridWebView, 
  Android.Webkit.WebView>
  {
       public bool _loadJS = false;

    public new static string Tag = "MyHybridWebViewRenderer";
    private static MyHybridWebView _xwebView;

    const string JavaScriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";


    protected override void OnElementChanged(ElementChangedEventArgs<MyHybridWebView> e)
    {
        base.OnElementChanged(e);
        _xwebView = e.NewElement as MyHybridWebView;

        if (Control == null)
        {

            var webView = new Android.Webkit.WebView(Forms.Context)
            {
                ScrollX = HorizontalScrollbarHeight,
                HorizontalScrollBarEnabled = false,
                VerticalScrollBarEnabled = false,
                ScrollBarSize = 0,
                Settings =
                {
                    JavaScriptEnabled = true,
                    DomStorageEnabled = true
                },                   
            };
            webView.SetWebViewClient(new ExtendedWebViewClient());

            SetNativeControl(webView);
        }
        if (e.OldElement != null)
        {

            Control.RemoveJavascriptInterface("jsBridge");

            var hybridWebView = e.OldElement as MyHybridWebView;
            hybridWebView.Cleanup();
        }
        if (e.NewElement != null)
        {
            if (_loadJS)
                return;


            var webView = e.NewElement as MyHybridWebView;
            Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");


            InjectJS(JavaScriptFunction);

            _loadJS = true;
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (Control == null || e.PropertyName == null)
            return;

        if (e.PropertyName == "LoadHtmlCode")
        {
            if (Element.LoadHtmlCode != null)
            {

                Control.LoadDataWithBaseURL("file:///android_asset/", _xwebView.LoadHtmlCode, "text/html", "UTF-8", null);

            }



        }
    }

    void InjectJS(string script)
    {
        if (Control != null)
        {
            Control.LoadUrl(string.Format("javascript: {0}", script));
        }
    }


    private class ExtendedWebViewClient : WebViewClient
    {

        public override async void OnPageFinished(aWebView view, string url)
        {

            DebugLogger.WriteLine("Start OnPageFinished ===========>");
            if (_xwebView != null)
            {
                var i = 120; //times of trying to get content 
                const int timeStep = 250; // millisecend

                await Task.Delay(500);
                while (i > 0) // wait here till content is rendered
                {
                    if (_xwebView.Terminate || _xwebView.Loaded)
                        break;

                    await Task.Delay(timeStep); //times of getting content                       

                    DebugLogger.WriteLine("Set WebView Height ============>" + view.ContentHeight , Tag);

                    _xwebView.HeightRequest = _xwebView.ContentHeight = view.ContentHeight + App.WebViewOverSize;
                    i--;
                }

                if (view.ContentHeight == 0 || i == 0)
                {
                    _xwebView.TimeOut = true;
                }
                await Task.Delay(500);

                _xwebView.HeightRequest = _xwebView.ContentHeight = view.ContentHeight + App.WebViewOverSize;

                DebugLogger.WriteLine("Content Is Loaded with height :" + (view.ContentHeight) + " =============>", Tag);
            }

            base.OnPageFinished(view, url);
            view.ClearCache(false);

      }



        public override void OnPageStarted(aWebView view, string url, Bitmap favicon)
        {

            if (!string.Equals(url.ToLower(), "file:///android_asset/") &&
                !(url.ToLower().Contains("https://dande6.com/wp-content/uploads/") &&
               (url.ToLower().Contains(".jpg") || url.ToLower().Contains(".png"))))
            {
                _xwebView.OpenLinkExternally(url);
                view.StopLoading();
                return;
            }

            base.OnPageStarted(view, url, favicon);
        }


     }


  }

}

这是我的jsBridge常见的:

namespace MyNameSpace.Droid.CallcSharpFromJs
{
public class JSBridge : Java.Lang.Object
{
    readonly WeakReference<MyHybridWebViewRenderer> hybridWebViewRenderer;

    public JSBridge(MyHybridWebViewRenderer hybridRenderer)
    {
        hybridWebViewRenderer = new WeakReference<MyHybridWebViewRenderer>(hybridRenderer);
    }

    [JavascriptInterface]
    [Export("invokeAction")]
    public void InvokeAction(string data)
    {
        MyHybridWebViewRenderer hybridRenderer;

        if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
        {
            hybridRenderer.Element.InvokeAction(data);
        }
    }
}

}

这是我的javascript

function invokeCSCode(data) {
    invokeCSharpAction(data);
}


jQuery(document).ready(function($) {

var $lg = $('.lightgallery');

$lg.lightGallery(); 

// Perform any action just before closing the gallery

$lg.on('onBeforeClose.lg', function (event) { invokeCSCode("OnCloseLightGallery"); });


// Perform any action just after opening the gallery

$lg.on('onAfterOpen.lg', function (event) { invokeCSCode("OnOpenLightGallery"); });

...

我非常需要你的帮助。请支持我。

1 个答案:

答案 0 :(得分:0)

@York Shen - MSFT 这是我的HTML代码:

<html>
<head>

<!--------------------- styles ------------------------>

<!---------- Light Gallery css  lightgallery - v1.2.22 - 2016-07-20 http://sachinchoolur.github.io/lightGallery/ --------->
<link rel="stylesheet" href="file:///android_asset/Content/CSS/lightgallery.min.css" type="text/css" media="all">


<!--------------------------------- jquery v3.6 stable ---------------------------------->
<script type="text/javascript" src="file:///android_asset/Content/JS/jquery.js"></script>

<!------ light gallery script dynamically gets the height according to device height ------>
<!-- here we copy and paste the light gallery script and change the height property dynamically by screen size like height:"627" -->
<script>
/*! lightgallery - v1.2.22 - 2016-07-20
* http://sachinchoolur.github.io/lightGallery/
* Copyright (c) 2016 Sachin N; Licensed Apache 2.0 */


</script>

<!--------------------------------- App script ---------------------------------->
<script type="text/javascript" src="file:///android_asset/Content/JS/AppScript.js"></script>

</head>
<body>
<p>اولین چینی توربو در بازار ایران</p>

<div class='lightgallery percent-20'><a class='large' title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-8.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-8-800x500.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-7.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-7-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-6.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-6-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-5.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-5-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-4.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-4-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-3.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-3-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-2.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-2-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-13.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-13-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-12.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-12-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-11.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-11-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-10.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-10-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-توربو.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-توربو-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-200x150.jpg'></a><a title='جک اس 5 - جک S5 ' href='https://dande6.com/wp-content/uploads/2014/12/جک-S5-9.jpg'><img src='https://dande6.com/wp-content/uploads/2014/12/جک-S5-9-200x150.jpg'></a></div>


</body>
</html>