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(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()
п
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 ответ
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()
на, как мы делаем с 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);