GWT JSNI javascript для Java не работает

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

У меня есть следующее в моем коде javascript.

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

    }

И в моем коде Java у меня есть следующее.

  public static native void exportStaticMethod() /*-{
    $wnd.onBackKeyDown = 
        $entry([email protected]::hideSettingsWidgets());

    }-*/;

Затем в onModuleLoad() я вызываю это так:

MyApp.exportStaticMethod();

Это не работает. У меня есть предупреждение в hideSettingsWidgets(), но оно никогда не отображается.

*EDIT* Вот еще немного кода. 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() {
        [email protected]::hideSettingsWidgets();
      });
      $doc.addEventListener("backbutton", onBackKeyDown, false);
    }-*/;

Поэтому я не уверен, где я ошибаюсь. Я не добавлял упомянутый вами ArrayList‹>, потому что не был уверен в этом, а прослушиватель событий не запускался при загрузке страницы.

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


person james    schedule 30.03.2012    source источник


Ответы (1)


Код 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 и что вы здесь делаете. Оборачивать функцию Java в вызов $entry и передавать его в $doc.addEventListener имеет наиболее логичный смысл (хотя я мало что знаю о WP7).

public static native void setupJavaHandler() /*-{
  var onBackKeyDown = $entry([email protected]::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() {
    [email protected]::hideSettingsWidgets();
  });
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;

Редактировать: К сожалению, оказывается, ваш метод все равно был статическим, поэтому this на самом деле ничего не значит! Либо измените exportStaticMethod/setupJavaHandler, чтобы они были нестатическими, и вызовите их напрямую (вероятно, в вашем onModuleLoad, как сейчас), либо передайте экземпляр для вызова hideSettingsWidgets(), как мы делаем с app в предыдущем примере.

public native void setupJavaHandler() /*-{
  var app = this;
  var onBackKeyDown = $entry(function() {
    [email protected]::hideSettingsWidgets();
  });
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;
// in onModuleLoad:
setupJavaHandler();

or

public static native void setupJavaHandler(MpApp app) /*-{
  //var app = this;
  var onBackKeyDown = $entry(function() {
    [email protected]::hideSettingsWidgets();
  });
  $doc.addEventListener("backbutton", onBackKeyDown, false);
}-*/;

// in onModuleLoad:
MyApp.setupJavaHandler(this);
person Colin Alworth    schedule 31.03.2012
comment
Привет. Код addEventListener не добавляется и не запускается при загрузке страницы, он специально добавлен в код Java. Я также удаляю его, вызывая функцию javascript. Я добавил свой соответствующий код выше. Спасибо за помощь. - person james; 31.03.2012
comment
Также, чтобы убедиться, нужна ли мне пустая функция onBackKeyDown на моей размещенной html-странице? - person james; 31.03.2012
comment
Он должен работать правильно. Я скачал GWT Phonegap, и он делает то же самое. Я не удивлюсь, если IE на мобильных устройствах не полностью поддерживает JSNI. - person james; 31.03.2012
comment
Привет, я подтвердил, что это проблема с GWT JSNI. Я сделал простое приложение HTML5, и код «кнопки возврата» работает правильно. Спасибо за помощь. - person james; 31.03.2012
comment
Я не совсем уверен, как ваше приложение GWT интегрируется с Phonegap, но если оно работает локально в браузере (а не загружается с сервера), вам необходимо убедиться, что GWT использует цель пользовательского агента ie6. - person funkybro; 31.03.2012