2

我正在尝试从我的 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());

    }-*/;

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

MyApp.exportStaticMethod();

它不起作用我有一个警报,hideSettingsWidgets()但它从来没有显示出来。

*编辑* 这是更多代码。Javascript 中未添加 EventListener。它是专门与 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<> 因为不确定,并且加载页面时事件侦听器没有运行。

似乎showSettingsWidgets()永远不会运行

4

1 回答 1

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!";

要解决此问题,您需要在其他问题(使用 GWT JSNI 添加 Eventlisteners to document)和您在此处执行的操作之间进行交叉。将 Java 函数包装在一个$entry调用中,并将其传递给$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 实例方法都需要在 athis上运行(并且 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);
于 2012-03-31T01:05:59.630 回答