我可以在Android(v2.2及更高版本)上从Java同步运行javascript吗?
我试图在我的Java android应用程序中运行一些javascript,但我需要它同步运行。WebView无法完成此操作,因为loadUrl和loadData没有返回类型。事实上,我在iOS的UIWebView上寻找的东西与此相当:我可以在Android(v2.2及更高版本)上从Java同步运行javascript吗?,javascript,android,Javascript,Android,我试图在我的Java android应用程序中运行一些javascript,但我需要它同步运行。WebView无法完成此操作,因为loadUrl和loadData没有返回类型。事实上,我在iOS的UIWebView上寻找的东西与此相当: - (NSString)stringByEvaluatingJavaScriptFromString:(NSString)script 我试着用Rhino,但它对我来说太慢了 谢谢 是的,但您必须使用。我相信它是同步的,但是,正如您正确指出的,无法从调用返回值
- (NSString)stringByEvaluatingJavaScriptFromString:(NSString)script
我试着用Rhino,但它对我来说太慢了
谢谢 是的,但您必须使用。我相信它是同步的,但是,正如您正确指出的,无法从调用返回值。丹提到了一个解决方案 首先,创建这样一个简单的类(假设返回类型是字符串): 保持此类的简单性和封装性非常重要,因为如果您从可能不可信的源加载HTML,它可能会给应用程序带来安全漏洞。也就是说,不要试图简单地传入您的活动并直接在其上使用Javascript调用方法 然后执行您想要的Javascript,给它一个回调实例来存储结果:
WebView webView = // ... get this from somewhere
MyCallback callback = new MyCallback();
webView.addJavaScriptInterface(callback, "callback");
webView.loadURL("javascript:callback.setReturnValue(someFunction())");
System.out.println("return value is " + callback.getReturnValue());
老问题,但我看没有答案。我是这样做的(但是要小心在这里阻塞UI线程(Kotlin) 然后运行如下操作:
webview.syncJsCall(
"""
(function() {
console.log("hello world");
MyApp.finished();
})()
""".trimIndent()
)
“我正在尝试从Java运行一些javascript…”从技术上讲,is语句是不正确的。我将措辞更改为更精确。不幸的是,这不起作用。loadURL不同步,因此当loadURL返回时,回调的结果尚未设置。这是@brindy答案的子集,但并不真正满足我的需要,因为出于我的目的,因为我需要整个调用是同步的nous java->js->java,比如stringByEvaluatingJavaScriptFromString:在ios中,除了我们的答案之外,没有其他API可以使用。
class MyWebView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
): WebView(context, attrs, defStyle) {
private val lock = ReentrantLock()
private val condition = lock.newCondition()
private inner class MyJsInterface {
@JavascriptInterface
fun finished() {
lock.withLock {
// Do stuff (Not the UI thread)
condition.signalAll()
}
}
}
private val jsInterface = MyJsInterface()
fun syncJsCall(js: String) {
lock.withLock {
loadUrl("javascript:$js")
condition.await()
}
}
init {
options.javascriptEnabled = true
addJavascriptInterface(jsInterface, "MyApp")
}
}
webview.syncJsCall(
"""
(function() {
console.log("hello world");
MyApp.finished();
})()
""".trimIndent()
)