【问题标题】:Passing callback from JavaScript to Java (Android)将回调从 JavaScript 传递到 Java (Android)
【发布时间】:2012-11-27 19:57:55
【问题描述】:

我正在使用 HTML5/JavaScript 开发适用于 Android 的应用程序。遇到限制,我想从 JavaScript 中调用在 Java 代码中实现的函数。更准确地说,我想创建某种类型的对话框。这相当容易(我只会给出一个粗略的轮廓/存根):

public class MyClass () {
    // other stuff

    public void createMyDialog (/* arguments */) {
        DialogBuilder builder = ...
        builder.setItems(myItems, new DialogInterface.OnClickListener () {
            @Override
            public void OnClick (DialogInterface dialog, int which) {
                droidGap.loadUrl(/* what now? */);
            }
        });
    }
}

然后这个类被显示给 JavaScript

MyClass myClass = new MyClass();
appView.addJavascriptInterface(myClass, "myClass");

到目前为止一切顺利。我现在可以从 JavaScript 中访问window.myClass.createMyDialog()然而,我想做的是传递一个回调,该回调将使用which 变量作为参数调用。这意味着有一个像

这样的签名
public void createMyDialog (final String callback)

并用类似的东西调用它

window.myClass.createMyDialog(
    function (which) {
        alert(which);
    }
);

我可以将函数作为字符串传递(在函数周围使用String())并从Java 调用appView.loadUrl("javascript:(" + callback + ")(" + which + ");");。 没关系,这个解决方案感觉不是很干净,它有一个很大的缺点 - 终于说到重点了。因为在 JavaScript 中,我实际上是在一个类中调用createMyDialog,我想做这样的事情:

function myJSClass () {
    this.myVar = -1;

    this.myFunc = function () {
        window.myClass.createMyDialog(
            function (which) {
                this.myVar = which;
            }
        );
    }
}

var myObj = new myJSClass();
myObj.myFunc();

现在的问题是,使用上面的解决方案,this 将引用 window 而不是类实例。这不是一个新问题,但是没有一个典型的解决方案(在调用之外存储var _this = this 并使用_this.myVar = which 或使用bind)作为this 的上下文完全丢失,因为该函数将从 Java 调用。

我知道它必须是可能的,因为 PhoneGap 框架提供了navigator.notification.confirm,它几乎完全符合我的要求。怎么走?

提前致谢!

【问题讨论】:

  • 我不太明白您是如何调用 createMyDialog()。在回调函数中,如果替换“this.myVar = which;”使用“console.log(which);”或“alert(which);”,你得到“which”的值了吗?
  • 是的,which 的值被正确传递。目前的问题是我无法控制在哪个上下文中执行回调。我不能使用_this 技巧,因为var _this = this; 会为方法创建一个局部变量,但回调是在全局上下文中执行的。

标签: java javascript android cordova


【解决方案1】:

首先,你真的应该write a Plugin。我们已经遇到了许多 Java/JS 和 JS/Java 问题,因此您应该利用我们测试过的代码。

其次,您需要在 UI 线程上运行对话框。不然就会出问题。

第三,如果您想在发生对话操作时从 Java 调用特定的成功/错误回调,您可以通过 PluginResult 类来实现。如果您设置了成功条件,则会调用成功回调,反之亦然。

查看 PG 代码以获取通知,其中包含许多对话框的示例:

https://git-wip-us.apache.org/repos/asf?p=cordova-android.git;a=blob;f=framework/src/org/apache/cordova/Notification.java;h=958ab26b842b41326523b9fa154aa8c71885c8ab;hb=HEAD

【讨论】:

  • 嗨,西蒙。伙计,你无处不在。我去看看,谢谢!
  • 谢谢,我把所有东西都切换到了插件系统。像魅力一样工作!
  • 我没有忘记 :) 我使用的结构与您链接到的通知插件中的结构相同。
猜你喜欢
  • 2012-02-18
  • 2014-03-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
相关资源
最近更新 更多