0

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.

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.