所以,每个人都知道我们创建一个扩展CordovaPlugin
的类并覆盖execute()
,然后在JS和本机Java(用于Android)之间创建一个桥梁。此外,我们使用PluginResult
将结果返回给JS。
因此,当JS向Java插件发出请求时,所有这些都会发生。我的问题是,如何将结果发送回JS (因此发送到HTML)异步?
我不知道这个词是否< strong>异步就在这里。问题是我想要发送一些东西回到JS(比如,当wifi变为启用/禁用时)。
我已经研究过这个但是没有任何适合我的情况。
我尝试过的是 -
BroadcastReceiver
类创建了一个WiFi
来监听WifiManager
个事件。
Toast
时弹出WiFi
,并使用CallbackContext
发送结果
MyPlugin.java
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, "Wifi
Connected"))
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
未发送给JS。
PS:听取WiFi事件不是我的实际问题,我想在Phonegap中复制PluginResult
应用。因此,它必须是异步的。
答案 0 :(得分:16)
你几乎就在那里,但你需要在PluginResult上将KeepCallback设置为true。如果不这样做,Java端的后续结果将不会在JavaScript端进行回调。这种编码的最好例子是Cordova核心中的网络插件。这是源的链接:
因此,您应该将代码更新为:
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;
}
}
}
}
答案 1 :(得分:11)
回答'第二回调'警告......
触发此警告的Cordova源代码可在第57行找到:
因此 - 引发警告是因为您的CallbackContext对象具有'finished = true'。
最有可能的原因是你打电话:callbackContext.sendPluginResult(pluginResult);
没有先致电:pluginResult.setKeepCallback(true);
如果不是......很可能你无意中缓存了CallbackContext对象。
你的execute()函数应该在每次调用时分配CallbackContext。请参阅code Simon linked to中的第125-127行:
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) {
if (action.equals("getConnectionInfo")) {`
this.connectionCallbackContext = callbackContext;
...
完整的事件顺序:
初次调用插件。
插件保存对传入的CallbackContext对象的引用。
保留CallbackContext对象引用,同时使用setKeepCallback(true)返回结果。
序列完成后,返回setKeepCallback(false)(默认值)
然后......
再次调用插件。
插件会覆盖保存的CallbackContext引用,替换为传入的对象。
然后步骤3-4与上述相同。
希望有所帮助:)