Android WebView javascript接口属性

Android WebView JavascriptInterface Property

本文关键字:属性 接口 javascript WebView Android      更新时间:2023-09-26

嘿,我正在使用一个应用程序,必须与一些javascript (coffeescript)代码接口。JS代码看起来像这样:

$(".content").on "click", ".feedback", ->
      window.webkit.foo.bar.message("hello")
      false
所以我需要添加一个javascript接口到我的WebView,如:
 webView.addJavascriptInterface(new Window(), "window");
 ...
 class Window {
   @JavascriptInterface
   public Webkit webkit() {
     return new Webkit();
   }
   class Webkit {
     @JavascriptInterface
     public Foo foo() {
 ...

我在这里遇到了两个问题,首先,它似乎你不能添加属性到全局窗口对象。其次,当我将接口名称更改为其他名称时,我似乎不知道如何添加属性而不是方法。

我可以让它以这样的方式工作:

  webkit().foo().bar().message("hello")

有人做过这样的事吗?

谢谢!

浏览器中的window对象(以及WebView)已经有了一个指向同一个对象的window属性。尝试在JavaScript调试器控制台中评估此值:

> window.window === window
< true

因此,尝试注入一个名称为"window"的Java对象将产生令人困惑的结果,并可能破坏代码,因为您可能会破坏这个不变量。

而且Java Bridge只通过属性公开函数对象,它不支持公开getter或setter。不过,您可以通过自己定义getter和setter来使用一点JavaScript魔法来克服这个问题。你需要在注入的对象上公开getter和setter方法,然后用JavaScript将它们赋值为属性getter setter。

因此,在Java中,方法的名称不同,例如:

webView.addJavascriptInterface(new Window(), "myWindow");
class Window {
  @JavascriptInterface
  public Webkit getWebkit() {
    return new Webkit();
  }
  ...

加载页面后,可以执行如下JavaScript代码:

Object.defineProperty(myWindow, 'webkit', { get: myWindow.getWebkit });

那么调用getWebkit()和访问myWindow上的webkit将意味着相同的事情。