如何使用JS直接在android JavaScriptSandbox中加载WebAssembly文件

问题描述 投票:0回答:1

我正在尝试使用 android 内的 asset 文件夹中的 WebAssembly。我有这个工作测试代码:

suspend fun runWebAssembly(): Result<String> = runCatchingCo {
    val isolate = getSandbox().createIsolate()

    val resources = applicationContext.resources
    val inputStream = resources.openRawResourceFd(R.raw.test).createInputStream()
    val addTwoWasm = inputStream.readBytes()
    val jsCode = "(async ()=>{" +
            "const wasm = await android.consumeNamedDataAsArrayBuffer('wasm_1');" +
            "const module = await WebAssembly.compile(wasm);" +
            "const instance = new WebAssembly.Instance(module);" +
            "return instance.exports.addTwo(20, 22).toString();" +
            "})()"

    isolate.provideNamedData("wasm_1", addTwoWasm)
    isolate.evaluateJavaScriptAsync(jsCode).await().also {
        isolate.close()
    }
}

问题是所需的 WebAssembly 文件将非常巨大(30mb),我想省略在 kotlin 中加载它们并直接将它们加载到 js 代码中。问题是没有一个节点像例如。 fetch 可用,而 import 似乎不起作用(未定义)。

"const wasm = await fetch('file:///android_asset/test.wasm');" //Does not work

有没有办法以某种方式添加缺少的依赖项以使用 fetch 或类似的东西,或者其他方式来加载这些文件?

javascript android webassembly
1个回答
0
投票

有运气吗? 首先,我尝试反转文档中给出的十六进制数据。我能够获得“add.wat”文件。但是当我将其转换为“add.c”时,似乎有些不对劲。 C 文件包含 500 多行代码,用于一个简单的添加函数。

此外,当我尝试加载使用十六进制创建的相同 add.wasm 文件时,我收到此错误:

java.util.concurrent.ExecutionException: androidx.javascriptengine.EvaluationFailedException: Uncaught TypeError: Cannot read properties of undefined (reading 'add')

我的代码:

    private fun initJs() {
    if (JavaScriptSandbox.isSupported()) {
        lifecycleScope.launch {
            val jsSandbox = createJsSandbox() ?: return@launch
            val jsIsolate = jsSandbox.createIsolate()

            val wasm = assets.open("check.wasm").readBytes() // Load WASM from assets

            val jsCode = "(async ()=>{" +
                    "const wasm = await android.consumeNamedDataAsArrayBuffer('wasm-1');" +
                    "const module = await WebAssembly.compile(wasm);" +
                    "const instance = WebAssembly.instantiate(module);" +
                    "return instance.exports.add(20, 22).toString();" +
                    "})()";

            try {
                jsIsolate.provideNamedData("wasm-1", wasm)
                val result = jsIsolate.evaluateJavaScriptAsync(jsCode).get()
                println(result)
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this@MainActivity, "JS Error: ${e.message}", Toast.LENGTH_LONG)
                    .show()
            } finally {
                jsIsolate.close()
                jsSandbox.close()
            }
        }
    } else {
        Toast.makeText(this, "JS NOT SUPPORTED", Toast.LENGTH_SHORT).show()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.