Cordova在Windows Phone 8中的多个回调 [英] Cordova multiple callbacks in Windows Phone 8

查看:226
本文介绍了Cordova在Windows Phone 8中的多个回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



问题是这样的:



当一个DispatchCommandResult被一个PluginResult调用时,KeepCallback设置为true,另一个DispatchCommand从另一个方法将调用它的回调和上一个回调更糟糕的是,如果第二个DispatchCommandResult有一个PluginResult,它的KeepCallback设置为false(默认值),那么这将取消任何进一步的回调



请考虑下面的代码。这是对Cordova Echo示例的修改。



echo方法将(通过DispatchCommandResult)调用javascript'success'回调与最初调用的相同的字符串经过几个JSON转换后)



repeat方法与echo相同,除了它在一个单独的线程中每5秒钟重复调用javascript'success'回调。 p>

如果调用repeat,然后在调用echo之后的某个点,echo方法中的DispatchCommandResult将导致echo成功和重复成功回调被调用,然后防止进一步重复成功回调,因为KeepCallback未设置为true。



在Android中,这个问题不是一个问题,因为Cordova提供的callbackId。但是,对于Windows Phone,无法访问callbackId。



C#代码

 命名空间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 []>
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]);
}

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

echo();



repeat();



echo();

示例输出

  Log:echo success:Hello
日志:重复成功:再次Hello
日志:重复成功:再次Hello
日志:再次
日志:重复成功:再次Hello
日志:重复成功:Hello
日志:echo success:Hello

有其他人有这个问题吗?如果是,是否有解决方法?

解决方案

我对cordova 2.5也有同样的问题,这是我发现的。



在cordova的(尚未发布)2.8版本中,如果您查看 BaseCommand.cs 。您可以看到 CurrentCommandCallbackId ,可用于跟踪您要调用的回调。



然后if您可以将KeepCallback设置为false,您可以将命令分派到所需的回调。



PhoneGap的当前版本是2.7.0,因此,必须克隆 2.8版本的cordova ,并复制<$ 插件 cordova cordivalib 模板/独立文件夹。



完成后,您可以使用此新功能:

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

然而,一旦Phonegap 2.8将会发布,应用程式正式版的Cordova。


I have a Cordova plugin which works fine for both Android & iOS. However, it fails when ported to Windows Phone 8 because it seems that multiple outstanding callbacks are not supported in Cordova for Windows Phone.

The problem is this:

When a DispatchCommandResult is called with a PluginResult which has KeepCallback set to true, a further DispatchCommand from a different method will call both its callback and the previous callback (the one with KeepCallback set to true).

Worse still, if the second DispatchCommandResult has a PluginResult which has KeepCallback set to false (the default) then this cancels any further callbacks which have KeepCallback set to true.

Example:

Consider the code below. It's a modification of the Cordova Echo sample.

The echo method will (via DispatchCommandResult) call the javascript 'success' callback with the same string which it was originally called with (after a couple of JSON conversions)

The repeat method does the same as echo except it repeatedly calls the javascript 'success' callback every 5 seconds in a separate thread.

If repeat is called and then at some point after echo is called, the DispatchCommandResult in the echo method will result in both the echo success and the repeat success callbacks being called and then prevent further repeat success callbacks because the KeepCallback was not set to true.

In Android this problem is not an issue because of the callbackId provided by Cordova. However, for Windows Phone, the callbackId is not accessible.

C# code

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 code

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();

Sample output

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"

Has anyone else had this problem? If so, is there a workaround? Am I doing anything wrong?

解决方案

I had the same problem with cordova 2.5 and this is what I found.

In the (not yet released) 2.8 version of cordova, if you look at the BaseCommand.cs of the cordovalib files. You can see a CurrentCommandCallbackId that can be used to keep track of the callback you want to call.

Then if you set the KeepCallback to false, you can dispatch the command to the wanted callback.

The current release of PhoneGap is the 2.7.0, so to use this you'll have to clone the 2.8 version of cordova and copy the content of Plugins, cordova and cordivalib of the templates/standalone folder.

Once done, you can use this new feature with something like:

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

However, once Phonegap 2.8 will be release, it will be safer to update your App with an official version of Cordova.

这篇关于Cordova在Windows Phone 8中的多个回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆