Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin Call Javascript function in Android without webView

Is there any way we can call JS function from Kotlin without having WebView in Android?

Let's say as mentioned below I have one JS function helloJS() in test.js file,

test.js:-

function helloJS(){
    return "Hello from JS"
}

And now I want to call this function from Kotlin file like

TestClass.kt:-

class TestHello{

    fun getHelloFromJS(){
        val name = test.helloJS()
    }
}

Till now I am using Webview and loading JS file into that and getting result as call back

But, I read that Kotlin is interoperable with JS like Java

So I am curious to know if there is any way we can use that on Android without having webView

like image 208
Santhi Bharath Avatar asked Nov 27 '17 16:11

Santhi Bharath


Video Answer


2 Answers

It's not possible. You must not confuse the language with the platform.

Kotlin is interoperable with JS like Java

means Kotlin/JS can use and be used in a Javascript platform (Node.js or browsers). The Kotlin code compiled (transpiled) into js is able to call other js files. And external Js code can call the js code build from Kotlin. This is the interoperability with JS.

There is no interoperability between Kotlin/JS and Kotlin/JVM.

enter image description here

like image 126
GaetanZ Avatar answered Nov 15 '22 18:11

GaetanZ


This is not possible straight forward but I found one library Execute JavaScript in Android without WebView for achieve this.

Read that blog carefully and follow below step.

Keep your JavaScript file (test.js) in assets folder in android project.

I have converted that code into Kotlin.

CallJavaScript.jks

import org.mozilla.javascript.Context
import org.mozilla.javascript.Function
import java.io.InputStreamReader


object CallJavaScript {

    fun callFunction(mContext: android.content.Context): Any? {

        var jsResult: Any? = null

        val params = arrayOf<Any>("")

        // Every Rhino VM begins with the enter()
        // This Context is not Android's Context
        val rhino = Context.enter()

        // Turn off optimization to make Rhino Android compatible
        rhino.optimizationLevel = -1
        try {
            val scope = rhino.initStandardObjects()

            // Note the forth argument is 1, which means the JavaScript source has
            // been compressed to only one line using something like YUI

            val assetManager = mContext.assets
            try {
                val input = assetManager.open("test.js")
                val targetReader = InputStreamReader(input)
                rhino.evaluateReader(scope, targetReader, "JavaScript", 1, null)
            } catch (e: Exception) {
                e.printStackTrace()
            }


            // Get the functionName defined in JavaScriptCode
            val obj = scope.get("helloJS", scope)

            if (obj is Function) {

                // Call the function with params
                jsResult = obj.call(rhino, scope, scope, params)
                // Parse the jsResult object to a String
                val result = Context.toString(jsResult)
            }
        } finally {
            Context.exit()
        }
        return jsResult
    }
}

Add this line to build.gradle:

implementation 'org.mozilla:rhino:1.7R4'

In your assets folder, create a file called test.js:

function helloJS()
{
    return "Hello from JS";
}

Now simply call above function from Activity.

 Log.e("JS : ", CallJavaScript.callFunction(this).toString());

Output :

E/JS :: Hello from JS
like image 36
Niranj Patel Avatar answered Nov 15 '22 19:11

Niranj Patel