[mono-android] WebView Javascript Interface and exposing methods through JNI
Tomasz Cielecki
tomasz at ostebaronen.dk
Mon Jan 9 06:33:58 EST 2012
Hi again,
I think I have narrowed it down to occur when trying to do this in a
Mono for Android Class Library project. If I put the code in a normal
project it compiles the Java code fine. Any reason to why it won't
work with a Class Library project?
On Mon, Jan 9, 2012 at 10:57 AM, Tomasz Cielecki <tomasz at ostebaronen.dk> wrote:
> Ok, I have been messing around a bit with this JNI stuff and can't
> seem to get it to work. The C# code compiles fine, so it must be the
> Java code that fails somehow as I get two errors:
>
> "C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj"
> (SignAndroidPackage target) (1) ->
> (_CompileJava target) ->
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(5,43):
> javac error : cannot find symbol
> [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(5,43):
> javac error : symbol : class AccessControlJavascriptNotify
> [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(5,43):
> javac error : location: package monodroid.watoolkit.library.login
> [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(5,43):
> javac error : extends
> monodroid.watoolkit.library.login.AccessControlJavascriptNotify
> [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(5,43):
> javac error : [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(15,2):
> error : method does not override or implement a method from a
> supertype [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(15,2):
> error : @Override
> [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
> obj\Debug\android\src\monodroid\watoolkit\library\login\AccessControlWebAuthActivity_AccessControlJavascriptNotify.java(15,2):
> error : [C:\Users\tcielecki\Desktop\MonoDroid.WAToolkit\MonoDroid.WAToolkit\MonoDroid.WAToolkit.Sample.csproj]
>
> Seems to me that it cannot find the java file I created even though I
> have set the build action to AndroidJavaSource, can it have anything
> to do with that I am doing this in a Mono for Android Class Library?
>
> I have tried to follow the Adder/ManagedAdder samples very closely and
> came up with this code, and as I said it compiles just fine.
>
> AccessControlJavascriptNotify.java:
>
> package monodroid.watoolkit.library.login;
>
> public class AccessControlJavascriptNotify
> {
> public void notify(String securityTokenResponse) { }
> }
>
> ManagedAccessControlJavascriptNotify.cs:
>
> using System;
> using Android.Runtime;
>
> namespace MonoDroid.WAToolkit.Library.Login
> {
> [Register("monodroid/watoolkit/library/login/AccessControlJavascriptNotify",
> DoNotGenerateAcw = true)]
> public abstract class ManagedAccessControlJavascriptNotify : Java.Lang.Object
> {
> static IntPtr class_ref =
> JNIEnv.FindClass("monodroid/watoolkit/library/login/AccessControlJavascriptNotify");
>
> public ManagedAccessControlJavascriptNotify ()
> {
> }
>
> public ManagedAccessControlJavascriptNotify(IntPtr handle,
> JniHandleOwnership transfer)
> : base (handle, transfer)
> {
> }
>
> protected override Type ThresholdType
> {
> get { return typeof(ManagedAccessControlJavascriptNotify); }
> }
>
> protected override IntPtr ThresholdClass
> {
> get { return class_ref; }
> }
>
> #region Notify
> static IntPtr id_notify;
>
> [Register("notify", "(Ljava/lang/String;)V", "GetNotifyHandler")]
> public virtual void Notify(string securityTokenResponse)
> {
> if (id_notify == IntPtr.Zero)
> id_notify = JNIEnv.GetMethodID(class_ref, "notify",
> "(Ljava/lang/String;)V");
> if (GetType() == ThresholdType)
> JNIEnv.CallVoidMethod(Handle, id_notify, new JValue[] { new
> JValue(new Java.Lang.String(securityTokenResponse)) });
> else
> JNIEnv.CallNonvirtualObjectMethod(Handle, ThresholdClass,
> id_notify, new JValue[] { new JValue(new
> Java.Lang.String(securityTokenResponse)) });
> }
>
> #pragma warning disable 0169
> static Delegate cb_notify;
> static Delegate GetNotifyHandler()
> {
> if (cb_notify == null)
> cb_notify = JNINativeWrapper.CreateDelegate((Action<IntPtr,
> IntPtr, string>)n_Notify);
> return cb_notify;
> }
>
> static void n_Notify(IntPtr jnienv, IntPtr lrefThis, string a)
> {
> ManagedAccessControlJavascriptNotify __this =
> Java.Lang.Object.GetObject<ManagedAccessControlJavascriptNotify>(lrefThis,
> JniHandleOwnership.DoNotTransfer);
> __this.Notify(a);
> }
> #endregion
> #pragma warning restore 0169
> }
> }
>
> And in my activity where I need this I have done:
>
> public class AccessControlJavascriptNotify :
> ManagedAccessControlJavascriptNotify
> {
> public override void Notify(string securityTokenResponse)
> {
> base.Notify(securityTokenResponse);
> }
> }
>
> Any Ideas?
>
>
> On Thu, Jan 5, 2012 at 8:38 PM, Tomasz Cielecki <tomasz at ostebaronen.dk> wrote:
>> Thank you Jon,
>>
>> I will see if I can get this to work.
>>
>> On Jan 5, 2012 6:53 PM, "Jonathan Pryor" <jonp at xamarin.com> wrote:
>>>
>>> On Jan 5, 2012, at 4:50 AM, Tomasz Cielecki wrote:
>>> > I am trying to add a javascript interface to my webview but it the
>>> > method in the object I pass to the webview does not get triggered.
>>> ...
>>> > I was thinking whether it is possible to tell mandroid to put the
>>> > methods in the generated Java files, so that Java knows of them.
>>>
>>> Yes, though as you saw it breaks because the Android Callable Wrapper use
>>> @Override, which breaks you.
>>>
>>> The solution [0] is a level of indirection: declare a Java-side interface,
>>> then bind that interface in C# and implement it. You'll still need to write
>>> some Java code, but only the interface declaration.
>>>
>>> Unfortunately, binding interfaces is more complicated. Fortunately, I have
>>> a sample:
>>>
>>>
>>> https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Adder.java
>>>
>>> https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/ManagedAdder.cs
>>>
>>> I also have docs, but those are awaiting review.
>>>
>>> - Jon
>>>
>>> [0] Yes, this isn't a very good solution. We'll be working on improving
>>> this in future releases.
>>>
>>> _______________________________________________
>>> Monodroid mailing list
>>> Monodroid at lists.ximian.com
>>>
>>> UNSUBSCRIBE INFORMATION:
>>> http://lists.ximian.com/mailman/listinfo/monodroid
>
>
>
> --
> Med Venlig Hilsen / With Best Regards
> Tomasz Cielecki
> http://ostebaronen.dk
--
Med Venlig Hilsen / With Best Regards
Tomasz Cielecki
http://ostebaronen.dk
More information about the Monodroid
mailing list