GWT JSNI javascript到Java无法正常工作

时间:2012-03-30 23:57:51

标签: gwt jsni

我正在尝试从我的Javascript代码调用Java方法。这适用于使用Phonegap的Windows Phone 7应用程序。

我的javascript代码中包含以下内容。

document.addEventListener("backbutton", onBackKeyDown, false);
 function onBackKeyDown(){

    }

在我的Java代码中,我有以下内容。

  public static native void exportStaticMethod() /*-{
    $wnd.onBackKeyDown = 
        $entry(this.@com.mycompany.myapp.client.MyApp::hideSettingsWidgets());

    }-*/;

然后在on onModuleLoad()中,我这样称呼它:

MyApp.exportStaticMethod();

它不起作用我在hideSettingsWidgets()中有警报但它永远不会显示。

*的 修改 * 这是一些更多的代码。 EventListener未添加到Javascript中。它特别添加了java代码。我无法让听众最初注册,所以这是我添加的内容。

public static native void removeBackListener() /*-{
   $wnd.removeTheListener();
}-*/;

在我的JavaScript中

function removeTheListener(){
        document.removeEventListener("backbutton", onBackKeyDown, false);

        }

以下是我对hideSettingsWidgets()

的电话
public void hideSettingsWidgets(){
        for(int i=0;i<settingsScreenWidgets.length;i++){
            settingsScreenWidgets[i].setVisible(false);
        }
        alertString("Working");
        removeBackListener();



    }

我正在调用你在showSettingsWidgets()

中给我的方法

P

rivate void showSettingsWidgets(){
        for(int i=0;i<settingsScreenWidgets.length;i++){
            settingsScreenWidgets[i].setVisible(true);
        }
        setCurrentImage();
        setOnOffImage();
        setupJavaHandler();

    }

它似乎确实添加了

中的EventListener
public native void setupJavaHandler() /*-{
      var app = this;
      var onBackKeyDown = $entry(function() {
        app.@com.mycompany.myapp.client.MyApp::hideSettingsWidgets();
      });
      $doc.addEventListener("backbutton", onBackKeyDown, false);
    }-*/;

所以我不确定我哪里出错了。我没有添加ArrayList&lt;&gt;你提到过因为不确定而且当页面被加载时事件监听器没有运行。

似乎showSettingsWidgets()永远不会运行

1 个答案:

答案 0 :(得分:2)

页面加载时,addEventListener代码可能正在运行,对吗?这会将空函数onBackKeyDown映射到后退按钮事件。然后,当您的模块加载时,您尝试重新定义 onBackKeyDown函数为新函数 - 但旧函数已经附加到您尝试收听的事件。

这大致相当于此(使用字符串而不是侦听器函数):

// first, make the thing to hold the 'listener', and define the first one
List<String> strings = new ArrayList<String>();
String onBackKeyDown = "abcd";
strings.add(onBackKeyDown);

// then, redefine the string, but don't change the list!
onBackKeyDown = "zyxw";

assert strings.contains(onBackKeyDown) : "Whoops, reassigned, but not added!";

要解决此问题,您需要在另一个问题Adding Eventlisteners to document with GWT JSNI之间以及您在此处执行的操作之间进行交叉。在$entry调用中包装Java函数,并将其传递给$doc.addEventListener是最合乎逻辑的意义(尽管我对WP7知之甚少)。

public static native void setupJavaHandler() /*-{
  var onBackKeyDown = $entry(this.@com.mycompany.myapp.client.MyApp::hideSettingsWidgets());
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;

还有一件事 - 记住我们在本机代码中编写JavaScript,调用this方法时会是hideSettingsWidgets()吗? JavaScript并不知道所有Java实例方法都需要运行this(并且JavaScript在B上运行对象A的方法没有问题 - A.method.call(B)是完全合法的,并且通常很有帮助)。我们需要确保this表示我们认为它的作用:

public static native void setupJavaHandler() /*-{
  var app = this;
  var onBackKeyDown = $entry(function() {
    app.@com.mycompany.myapp.client.MyApp::hideSettingsWidgets();
  });
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;

编辑:哎呀,结果你的方法无论如何都是静态的,所以this实际上并不意味着什么!将exportStaticMethod / setupJavaHandler更改为非静态并直接调用(可能在您现在拥有的onModuleLoad中),或传入实例以调用hideSettingsWidgets()就像我们在上一个示例中使用app一样。

public native void setupJavaHandler() /*-{
  var app = this;
  var onBackKeyDown = $entry(function() {
    app.@com.mycompany.myapp.client.MyApp::hideSettingsWidgets();
  });
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;
// in onModuleLoad:
setupJavaHandler();

public static native void setupJavaHandler(MpApp app) /*-{
  //var app = this;
  var onBackKeyDown = $entry(function() {
    app.@com.mycompany.myapp.client.MyApp::hideSettingsWidgets();
  });
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;

// in onModuleLoad:
MyApp.setupJavaHandler(this);