问题
Is is possible to call javascript functions from kotlin JVM based project? Like for example I got class:
class JS{
fun callJS( ){
// somehow call js function
}
}
回答1:
You can use a ScriptEngineManager with JavaScript as the engine.
You use ScriptEngineManager.getEngineByName to get the engine itself, but that doesn't allow calling methods from Java. In order to do this, you need an Invocable. This is done by first eval
uating the script (either as a Reader or String) and then casting it as an Invocable.
I personally prefer using two extension functions for this. You don't need both, but there's one for Readers and one for Strings:
fun String.createInvocable(engine: ScriptEngine) : Invocable {
engine.eval(this);
return engine as Invocable;
}
fun Reader.createInvocable(engine: ScriptEngine) : Invocable{
engine.eval(this)
return engine as Invocable
}
The engine here is the JavaScript engine, and it uses it to eval the either String with the code or reader to the file with the code. It really depends on how you store it.
And then you use the Invocable to call the function.
Note that it returns null if there's nothing returned from the function, otherwise it gives a non-null object. That assumes null isn't being returned of course.
Anyways, for the actual engine. ScriptEngineManager is in the javax package, so you don't need to add any dependencies or libraries to use it. You need a ScriptEngineManager in order to get the engine itself:
val engineManager = ScriptEngineManager()
The ScriptEngineManager is just a manager of the engines. It can't be used directly for evaluating, since it isn't the engine. Since you want the JavaScript engine, you call getEngineByName
, and pass javascript
:
val engine = engineManager.getEngineByName("javascript")
And this is where the extension functions come in. Create a new Reader (or use the String with the source if you prefer) and call createInvocable:
val invocable = Files.newBufferedReader(Paths.get("dir")).createInvocable(engine)
And finally, call the function:
invocable.invokeFunction("name", "arguments")//there can be no arguments
If you have return values, add a var, or val to catch it.
来源:https://stackoverflow.com/questions/49554822/call-javascript-function-from-kotlin-jvm-based-project