11

有什么方法可以从 Kotlin 调用 JS 函数而无需在 Android 中使用 WebView?

假设如下所述,我helloJS()test.js文件中有一个 JS 函数,

test.js:-

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

现在我想从 Kotlin 文件中调用这个函数,比如

测试类.kt:-

class TestHello{

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

到目前为止,我正在使用 Webview 并将 JS 文件加载到其中并获取结果作为回调

但是,我读到Kotlin 可以与 Java 等 JS 互操作

所以我很想知道是否有任何方法可以在没有 webView 的情况下在 Android 上使用它

4

4 回答 4

9

这不可能直截了当,但我发现一个库在没有 WebView 的情况下在 Android 中执行 JavaScript来实现这一点。

仔细阅读该博客并按照以下步骤操作。

将您的JavaScript文件 ( test.js) 保存在 android 项目的 assets 文件夹中。

我已将该代码转换为 Kotlin。

调用JavaScript.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
    }
}

将此行添加到build.gradle

implementation 'org.mozilla:rhino:1.7R4'

在您的assets文件夹中,创建一个名为test.js

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

现在只需从 Activity 调用上述函数。

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

输出 :

E/JS :: Hello from JS
于 2018-03-19T07:26:59.300 回答
7

这是不可能的。您不得将语言与平台混淆。

Kotlin 可与 Java 等 JS 互操作

表示 Kotlin/JS 可以在 Javascript 平台(Node.js 或浏览器)中使用和使用。编译(转译)成 js 的 Kotlin 代码可以调用其他 js 文件。并且外部 Js 代码可以调用 Kotlin 构建的 js 代码。这就是与 JS 的互操作性。

Kotlin/JS 和 Kotlin/JVM 之间没有互操作性。

在此处输入图像描述

于 2018-03-17T22:55:40.853 回答
0

我不是 Kotlin 的专业人士,但 Java 对我来说是一个馅饼。您可以在 Java 中实现的任何东西都可以在 Kotlin 中实现并执行 Javascript 代码,我使用 rhino,它比使用 webview 更容易实现它:

try {
   Scriptable scope = rhino.initStandardObjects();
   rhino.evaluateString(scope, javaScriptCode, "JavaScript", 1, null);
   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, params);
       // Parse the jsResult object to a String
       String result = Context.toString(jsResult);
   }

}finally {
   Context.exit();
}
于 2018-03-22T11:18:41.503 回答
0

Kt 看起来像 JS,其实不然。它将为 Android 运行时编译,而不是为 java 脚本引擎编译。

JS 代码需要一个 JS 运行时,但它不在 Android 运行时中。

即你不能直接在Android 的Java/Kt 代码中运行JS。

于 2018-03-22T09:56:38.960 回答