我正在尝试使用 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 或类似的东西,或者其他方式来加载这些文件?
有运气吗? 首先,我尝试反转文档中给出的十六进制数据。我能够获得“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()
}
}