I have a Capacitor plugin (Android) that has a method named “flyToVenus” to perform some complex work. This plugin method eventually determines that it needs to call back to JavaScript for it to do some of the work. So the plugin method then calls back to JavaScript with “notifyListeners” to force JavaScript to perform its work. The tricky part is that I need the native plugin code to wait for JavaScript to finish its work before continuing in the native code.
An obvious solution would be for JavaScript to do its work before calling the plugin, and then JavaScript could pass the results to the plugin up front. But this is impossible in my scenario for reasons too complicated to explain here.
@PluginMethod
public void flyToVenus(PluginCall call) {
/* ... do some processing in the plugin ... */
/* plugin decides it needs to call JavaScript so that it can perform some work */
this.savedResult = -1;
JSObject data = new JSObject();
data.put("value1",42);
data.put("value2",37);
notifyListeners("addTwoValues",data);
/* now imagine that the JavaScript code receives the "addTwoValues" event and */
/* computes the result of 79. The JavaScript code then invokes another plugin */
/* method named "provideResult" (shown below) and sends back the value 79.*/
while (this.savedResult < 0) {
try { Thread.sleep(10); } catch (InterruptedException ignored) {}
}
int result = this.savedResult;
/* now do so more processing with the "result" value */
call.resolve();
}
@PluginMethod
public void provideResult(PluginCall call) {
this.savedResult = call.getInt("result");
call.resolve();
}
Obviously the above Java plugin code does not work as intended-- it blocks forever in the while-loop. I think the problem is that when I loop and wait for JavaScript to call the “provideResult” plugin method, nothing can actually happen because JavaScript’s main thread is blocked by my own wait loop.
My question is, how can I simulate this behavior? Is there some call I can put into my while loop that will force the JavaScript main thread to execute the next microtask in its queue? Or some other way to invoke JavaScript code from a plugin method that is already running?