Reputation: 504
I would like to call a javascript function with parameters from Java in an android app, I don't need to load it in webview as I just need to call it and get the results from the JS file which is in the assets folder.
I did it on iOS using JavascriptCore, but I can't find the same functionality in android.
Looked up AndroidJSCore and Rihno but the docs and tutorials are not clear on the subject.
I load the JS file into a String , further I can't go as how to send the parameters and get the results.
Here is how load the file into a string :
AssetManager assetManager = getAssets();
String jsFile;
// To load js file
InputStream input;
try {
input = assetManager.open("authenticate.js");
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
// byte buffer into a string
jsFile = new String(buffer);
resultTV.setText(jsFile);
Log.d("TAG", jsFile);
} catch (IOException e) {
e.printStackTrace();
}
The parameters to send come from Edittexts.
The javascript function take 2 parameters and return JSON
function authenticate(uName, pWord)
{
var authenString = JSON.stringify(authenJSON);
return authenString;
}
Any help is appreciated.
Upvotes: 0
Views: 1040
Reputation: 5498
Here's how I use Rhino in Android:
/**
*
* @param javaScriptCode
* @param functionNameInJavaScriptCode
* @param params Do not pass an array of primitives! For example if passing doubles, pass Double[], not double[]
* @return
*/
public Map<String,Object> execute(String javaScriptCode, String functionNameInJavaScriptCode, Iterable<String> returnObjectKeys, Object... params){
Map<String,Object> rtn = null;
// Every Rhino VM begins with the enter()
// This Context is not Android's Context
Context rhino = Context.enter();
// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
try {
final Object[] parameters = new Object[params.length + 1];
for(int i=0; i < params.length; i++){
parameters[i] = params[i];
}
parameters[parameters.length - 1] = BuildConfig.DEBUG;
Scriptable scope = rhino.initStandardObjects();
rhino.evaluateString(scope, javaScriptCode, "JavaScript", 1, null);
// Get the functionName defined in JavaScriptCode
Object obj = scope.get(functionNameInJavaScriptCode, scope);
if (obj instanceof Function) {
Function jsFunction = (Function) obj;
// Call the function with params
Object jsResult = jsFunction.call(rhino, scope, scope, parameters);
if(jsResult == null){
return null;
}
Scriptable s = (Scriptable) jsResult;
rtn = convert(s, returnObjectKeys);
}
else {
throw new IllegalArgumentException("No function " + functionNameInJavaScriptCode + " found in supplied script");
}
} finally {
Context.exit();
}
return rtn;
}
private Map<String,Object> convert(Scriptable object, Iterable<String> keys){
Map<String,Object> rtn = new HashMap<>();
for(String s : keys){
if(object.has(s,object)){
rtn.put(s, object.get(s, object));
}
}
return rtn;
}
I think I got most of this from SO but can't find the question now.
Upvotes: 1