首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Javascript和Phonegap插件之间的异步通信?

Javascript和Phonegap插件之间的异步通信?
EN

Stack Overflow用户
提问于 2018-03-02 01:43:11
回答 2查看 0关注 0票数 0

所以,每个人都知道我们让一个类扩展CordovaPlugin并覆盖它 execute(),然后在JS和本地Java(for Android)之间创建一个桥梁。我们进一步使用PluginResult将结果返回给JS。

所以,所有这些都发生在从JS发出的对Java插件的请求中。我的问题是,如何将结果异步发送回JS(并因此发送到HTML)

我不知道异步这个词是否在这里。事情是我想发送一些东西回蓝色的JS(例如,当wifi成为启用/禁用时)。

我已经研究过这个,但没有得到任何适合我的案例。

我试过的东西是 -

  • 创建一个使用该类BroadcastReceiverWiFi事件监听WifiManager
  • 注册接收器。
  • 最后,弹出一个Toastwhen WiFi启用/禁用,并发送结果使用 CallbackContext callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, "Wifi Connected"))和断开与不同的消息。

MyPlugin.java

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;

...

public class MyPlugin extends CordovaPlugin {
private WifiReceiver wifiBroadcastReceiver = null;
private CallbackContext callbackContext = null;

...

    public MyPlugin() {     
        wifiBroadcastReceiver = new WifiReceiver();
    ...
    }
    ...
    public boolean execute(String action, final JSONArray args,
            final CallbackContext callbackId) throws JSONException {
        IntentFilter wifiFilter = new IntentFilter(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        cordova.getActivity().registerReceiver(wifiBroadcastReceiver, wifiFilter);
        this.callbackContext = callbackId;

    ...
    }
    public class WifiReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
                if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
                    Toast.makeText(cordova.getActivity(), "Wifi Connected", Toast.LENGTH_SHORT).show();
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, "Wifi Connected"));
                } else {
                    Toast.makeText(cordova.getActivity(), "Wifi Disconnected", Toast.LENGTH_SHORT).show();
                    callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, "Wifi Disconnected"));
                }
            }           
        }

}

Toast持久性有机污染物,但PluginResult不发送给JS。

PS:听WiFi事件不是我的实际问题,我想Android Bluetooth Chat在Phonegap中复制应用程序。所以,它必须是异步的。

EN

回答 2

Stack Overflow用户

发布于 2018-03-02 09:43:29

你几乎在那里,但你需要在你的PluginResult上设置KeepCallback为true。如果你不这样做,Java端的后续结果将不会在JavaScript端有回调。这种编码最好的例子是Cordova核心中的网络插件。这是一个链接到源:

https://git-wip-us.apache.org/repos/asf?p=cordova-plugin-network-information.git;a=blob;f=src/android/NetworkManager.java;h=e2ac500ccc885db641d5df6dab8eae23026a5828;hb=HEAD

所以你应该更新你的代码:

public boolean execute(String action, final JSONArray args,
        final CallbackContext callbackId) throws JSONException {
    IntentFilter wifiFilter = new IntentFilter(
            WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
    cordova.getActivity().registerReceiver(wifiBroadcastReceiver,
            wifiFilter);
    this.callbackContext = callbackId;
    PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
    result.setKeepCallback(true);
    this.callbackContext.sendPluginResult(result);
    return true;
}

public class WifiReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
            PluginResult result;
            if (intent.getBooleanExtra(
                    WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
                Toast.makeText(cordova.getActivity(), "Wifi Connected",
                        Toast.LENGTH_SHORT).show();
                result = new PluginResult(PluginResult.Status.OK,
                        "Wifi Connected");
            } else {
                Toast.makeText(cordova.getActivity(), "Wifi Disconnected",
                        Toast.LENGTH_SHORT).show();
                result = new PluginResult(PluginResult.Status.ERROR,
                        "Wifi Disconnected");
            }

            result.setKeepCallback(false);
            if (callbackContext != null) {
                callbackContext.sendPluginResult(result);
                callbackContext = null;
            }
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2018-03-02 11:38:21

回答'second callback'警告...

触发此警告的Cordova源代码可以在第57行找到:

https://github.com/apache/cordova-android/blob/master/framework/src/org/apache/cordova/CallbackContext.java

因此 - 警告是由于您的CallbackContext对象具有'finished = true'造成的。

最有可能的原因是你叫做: callbackContext.sendPluginResult(pluginResult);

没有先打电话: pluginResult.setKeepCallback(true);

如果没有......很可能你无意中缓存了CallbackContext对象。

每次调用execute()函数时都应该分配CallbackContext。请参阅Simon链接到代码行125-127 :

public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {

if (action.equals("getConnectionInfo")) {`

this.connectionCallbackContext = callbackContext;

...

完整的事件顺序:

  1. 初次调用插件。
  2. 插件保存对传入CallbackContext对象的引用。
  3. 保留CallbackContext对象引用,同时用setKeepCallback(true)返回结果。
  4. 当序列完成时,返回setKeepCallback(false)(默认)

然后......

  1. 再次调用插件。
  2. 插件覆盖保存的CallbackContext引用,用传入的对象替换。

然后步骤3-4与上面相同。

希望帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档