【问题标题】:Cordova multiple callbacks in Windows Phone 8Windows Phone 8 中的 Cordova 多个回调
【发布时间】:2013-02-07 17:26:23
【问题描述】:

我有一个适用于 Android 和 iOS 的 Cordova 插件。但是,它在移植到 Windows Phone 8 时会失败,因为在 Cordova for Windows Phone 中似乎不支持多个未完成的回调。

问题是这样的:

当使用将 KeepCallback 设置为 true 的 PluginResult 调用 DispatchCommandResult 时,来自不同方法的另一个 DispatchCommand 将同时调用其回调和前一个回调(KeepCallback 设置为 true 的回调)。

更糟糕的是,如果第二个 DispatchCommandResult 的 PluginResult 将 KeepCallback 设置为 false(默认值),那么这将取消任何进一步将 KeepCallback 设置为 true 的回调。

示例

考虑下面的代码。这是对 Cordova Echo 样本的修改。

echo 方法将(通过 DispatchCommandResult)调用 javascript 的“成功”回调,使用与最初调用相同的字符串(经过几次 JSON 转换)

repeat 方法的作用与 echo 相同,只是它在单独的线程中每 5 秒重复调用一次 javascript 'success' 回调。

如果调用repeat,然后在调用echo 之后的某个时间点,echo 方法中的DispatchCommandResult 将导致echo 成功和repeat 成功回调都被调用,然后阻止进一步的重复成功回调,因为没有设置KeepCallback为真。

在 Android 中,由于 Cordova 提供了 callbackId,所以这个问题不是问题。但是,对于 Windows Phone,callbackId 是不可访问的。

C#代码

namespace Cordova.Extension.Commands
{
    public class Echo : BaseCommand
    {
        public void echo(string options)
        {
            string optVal = JsonHelper.Deserialize<string[]>(options)[0];
            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, optVal));
        }
        public void repeat(string options)
        {
            string optVal = JsonHelper.Deserialize<string[]>(options)[0];
            ThreadStart worker = () =>
            {
                try
                {
                    while (true)
                    {
                        Thread.Sleep(5000);
                        PluginResult r = new PluginResult(PluginResult.Status.OK, optVal);
                        r.KeepCallback = true;
                        DispatchCommandResult(r);
                    }
                }
                catch (Exception ex)
                {
                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message));
                }
            };
            new Thread(worker).Start();
        }
    }
}

JavaScript 代码

function echo() {
    function success(message) {
        console.log("echo success: " + message);
    }
    function error(e) {
        console.log("echo error: " + e);
    }
    cordova.exec(success, error, "Echo", "echo", ["Hello"]);
}

function repeat() {
    function success(message) {
        console.log("repeat success: " + message);
    }
    function error(e) {
        console.log("repeat error: " + e);
    }
    cordova.exec(success, error, "Echo", "repeat", ["Hello again"]);
}

echo();
.
.
.
repeat();
.
.
.
echo();

样本输出

Log:"echo success: Hello"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello"
Log:"echo success: Hello"

还有其他人遇到过这个问题吗?如果是这样,是否有解决方法?我做错什么了吗?

【问题讨论】:

  • 你找到解决办法了吗?

标签: windows-phone-8 cordova windows-phone phonegap-plugins cordova-2.0.0


【解决方案1】:

我在使用 cordova 2.5 时遇到了同样的问题,这就是我发现的。

在cordova(尚未发布)2.8 版本中,如果您查看cordovalib 文件的BaseCommand.cs。你可以看到一个CurrentCommandCallbackId,它可以用来跟踪你想要调用的回调。

然后,如果您将 KeepCallback 设置为 false,您可以将命令分派给想要的回调。

PhoneGap 的当前版本是 2.7.0,因此要使用它,您必须克隆 2.8 version of cordova 并复制 templates/standalone 文件夹的 Pluginscordovacordivalib 的内容.

完成后,您可以通过以下方式使用此新功能:

private void DispatchMessage(PluginResult.Status status, string message, bool keepCallback, string callBackID)
{
    PluginResult res = new PluginResult(status, message);
    res.KeepCallback = keepCallback;
    DispatchCommandResult(res, callBackID);
}

不过,一旦 Phonegap 2.8 发布,使用 Cordova 的正式版本更新您的应用程序会更安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多