[mono-android] WebView Javascript Interface and exposing methods through JNI
Tomasz Cielecki
tomasz at ostebaronen.dk
Mon Jan 9 04:57:51 EST 2012
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
More information about the Monodroid
mailing list