3

few months ago I had a custom Xamarin.Android renderer for a webview based on the sample code in https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview

Javascript code was perfectly invoking my C# code however recently after the latest updates, the WebView control is no longer able to invoke the C# action, (to be more precise, if I am targeting Android 9.0 (API level 28) or higher) using API level 27 still works fine

after more investigation, I figured out that the compiler gives a warning on [JavascriptInterface] is being obsolete! https://learn.microsoft.com/en-us/dotnet/api/android.webkit.javascriptinterface?view=xamarin-android-sdk-9 and they advised to use the (IJavascriptInterface) instead

here is the code to be reviewed

[JavascriptInterface]
[Export ("invokeAction")]
public void InvokeAction (string data)
{
    HybridWebViewRenderer hybridRenderer;
    if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget (out hybridRenderer))
    {
        hybridRenderer.Element.InvokeAction (data);
    }
}

Does anyone know how to implement this properly to fix that and get Javascript to invoke my C# code again.

Abdul
  • 33
  • 5
  • Error CS0653: Cannot apply attribute class 'IJavascriptInterface' because it is abstract (CS0653) (CustomRenderer.Droid) – Abdul Nov 07 '19 at 05:38
  • The example HTML in https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview has problem on Android 9 and above - `` should actually be ``. The https is very important, otherwise Android will refuse to load the jquery and cause the javascript to be invalid. Took me half day to figure that's the actual problem when all my renderers are actually already working fine. – Nik A. Oct 07 '20 at 14:59

1 Answers1

5

it still works in my Xamarin.Android project with [JavascriptInterface]

this is part of my sample :

var webview = FindViewById<WebView>(Resource.Id.webView1);
WebSettings settings = webview.Settings;
settings.JavaScriptEnabled = true;
// load the javascript interface method to call the foreground method
webView.AddJavascriptInterface(new MyJSInterface(this), "CSharp");
webview.SetWebViewClient(new WebViewClient());

MyJSInterface class :

class MyJSInterface : Java.Lang.Object
{
  Context context;

 public MyJSInterface (Context context)
  {
    this.context = context;
  }

 [JavascriptInterface]
 [Export]
 public void ShowToast (string msg)
  {
    Toast.MakeText(context, msg, ToastLength.Short).Show();
  }
}

and in html :

<button type="button" onClick="CSharp.ShowToast ('Call C#')">Call C#</button>

you could refer to https://stackoverflow.com/a/54069075/10768653

Leo Zhu
  • 15,726
  • 1
  • 7
  • 23
  • Thanks for the reply; to be more accurate, It works if you are targeting Android 8.1 (API level 27) or less. but if you try targeting Android 9 (API level 28) or above it will fail to work – Abdul Nov 07 '19 at 03:04
  • i test it with Android 9.it works in my Xamarin.Android project,i will test in Xamarin.Forms project later,and tell you result. – Leo Zhu Nov 07 '19 at 03:05
  • Thanks, I am using Xamarin.Forms (4.3.0.947036) – Abdul Nov 07 '19 at 03:09
  • @Abdula i test it in Xamarin.Forms project,the code above also works – Leo Zhu Nov 07 '19 at 05:05
  • Thanks Leo, I was tracing the log on application output and I came across the following line: [chromium] [INFO:CONSOLE(16)] "Uncaught ReferenceError: $ is not defined", source: file:///android_asset/Content/index.html (16) for some reason the html was unable to load the JQuery file when targeting Android 9.0, so for testing purposes I removed JQuery and the C# method was invoked successfully, Now I want to figure out why the JQuery failed to load on Android 9 :) your comment helped me to search on another spot, Thanks again – Abdul Nov 07 '19 at 05:34
  • But I am still unsure for future if the [JavascriptInterface] attribute should be replaced with an implementation of the newly introduced interface, at least I hope the code compatibility will not break in future. – Abdul Nov 07 '19 at 05:45
  • 1
    @Abdul don't worry,as [IJavascriptInterface](https://learn.microsoft.com/en-us/dotnet/api/Android.Webkit.IJavascriptInterface?view=xamarin-android-sdk-9) said.Annotation that allows exposing methods to JavaScript.`[JavascriptInterface]` is the annotation – Leo Zhu Nov 07 '19 at 06:08