Hey I am working with an app that has to interface with some javascript (coffeescript) code. The code JS code looks something like this:
$(".content").on "click", ".feedback", ->
window.webkit.foo.bar.message("hello")
false
So I need to add a javascript interface to my WebView like:
webView.addJavascriptInterface(new Window(), "window");
...
class Window {
@JavascriptInterface
public Webkit webkit() {
return new Webkit();
}
class Webkit {
@JavascriptInterface
public Foo foo() {
...
I am running into two problems here, first it appears you can't add properties to the global window object. And second when I change my interface name to something else, I can't seem to figure out how to add properties rather than methods.
I can get it to work in a way like this:
webkit().foo().bar().message("hello")
Has anyone done anything like this?
Thanks!
Hey I am working with an app that has to interface with some javascript (coffeescript) code. The code JS code looks something like this:
$(".content").on "click", ".feedback", ->
window.webkit.foo.bar.message("hello")
false
So I need to add a javascript interface to my WebView like:
webView.addJavascriptInterface(new Window(), "window");
...
class Window {
@JavascriptInterface
public Webkit webkit() {
return new Webkit();
}
class Webkit {
@JavascriptInterface
public Foo foo() {
...
I am running into two problems here, first it appears you can't add properties to the global window object. And second when I change my interface name to something else, I can't seem to figure out how to add properties rather than methods.
I can get it to work in a way like this:
webkit().foo().bar().message("hello")
Has anyone done anything like this?
Thanks!
Share Improve this question edited Sep 9, 2015 at 12:44 trev9065 asked Sep 9, 2015 at 4:49 trev9065trev9065 3,5015 gold badges34 silver badges45 bronze badges 5- I do not understand your target :-( First of all you can not return a Java object (Webkit) to javascript as described here: stackoverflow./questions/9105059/…. Use primitives or String (maybe JSON) instead. – A.D. Commented Sep 9, 2015 at 5:50
- ah that makes more sense. Thanks for the tip. – trev9065 Commented Sep 9, 2015 at 12:45
- So after reading that there is no real way to pass object properties through since only primitives can be sent? @user2281606 – trev9065 Commented Sep 9, 2015 at 12:58
- yes, just primitives + strings. Is your target to show a native dialog with "webkit().foo().bar().message("hello")"? Sorry for probing – A.D. Commented Sep 10, 2015 at 12:23
- I am not trying to show a dialog specifically. The reason for doing the dot notation is that is how our iOS clients native functions are defined. – trev9065 Commented Sep 10, 2015 at 12:35
1 Answer
Reset to default 5The window
object in browsers (and in WebView) already has a window
property, which points back to the same object. Try evaluating this in your JavaScript debugger console:
> window.window === window
< true
So trying to inject a Java object with a name "window"
would produce confusing results and may break code, since you will likely break this invariant.
And it is also true that Java Bridge only exposes function objects through properties, it doesn't support exposing getters or setters. Though, you can overe that with a bit of JavaScript magic by defining getters and setters yourself. You will need to expose getter and setter methods on your injected object and then assign them to be property getter setters with JavaScript.
So, in Java you name method differently, e.g.:
webView.addJavascriptInterface(new Window(), "myWindow");
class Window {
@JavascriptInterface
public Webkit getWebkit() {
return new Webkit();
}
...
And then after you have loaded the page, you can execute JavaScript code like this:
Object.defineProperty(myWindow, 'webkit', { get: myWindow.getWebkit });
Then both calling getWebkit()
and accessing webkit
on myWindow
will mean the same thing.