GWT JSNI JavaScript для Java не работает - PullRequest
2 голосов
/ 31 марта 2012

Я пытаюсь вызвать метод Java из моего кода Javascript.Это для приложения Windows Phone 7, использующего Phonegap.

В моем коде 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(), но оно никогда не показывается.

* РЕДАКТИРОВАТЬ * Вот еще немного кода.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 <>, который вы упомянули, потому что не был уверен, и слушатель событий не работал, когда страница была загружена.

Похоже, showSettingsWidgets() никогда не запускается

1 Ответ

2 голосов
/ 31 марта 2012

Код addEventListener, вероятно, работает при загрузке страницы, верно?Это отобразит вашу пустую функцию onBackKeyDown на событие backbutton.Затем, когда ваш модуль загружается, вы пытаетесь переопределить функцию 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!";

Чтобы исправить это, вам нужно помесь того, что вы делаете в другом вопросе, Добавление Eventlisteners вдокумент с GWT JSNI , и что вы здесь делаете.Заключение 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 требуется this для запуска (и JavaScript не имеет проблем с запуском методов для объекта A на B - 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() on, как мы делаем с 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);
...