我正在使用WebView构建混合Android应用,并通过JavaScriptInterface
注释与设备进行通信
来自WebView:
webView.addJavascriptInterface(someService, "someService");
服务实施:
@JavascriptInterface
public void someMethod() {
//do some business logic..
}
问题在于我从JavaScript运行它:
function callSomeMethod() {
someService.someMethod()
};
这个调用是同步的,并希望能像异步那样运行:
function callSomeMethod(callback) {
someService.someMethod(function(result) {
if (result == 'success')
callback();
})
};
最好使用承诺:
function callSomeMethod() {
return someService.someMethod()
//someMethod returns promise
};
Android WebView是否内置支持异步运行JavaScript代码?
答案 0 :(得分:5)
这完全取决于你。您只需要从注入的方法立即返回,但能够在执行完成时调用JS代码。这样的事情(请注意,这只是一个粗略的草图):
private WebView mWebView;
private final Object mLock = new Object();
private String mJsCallbackCode;
@JavascriptInterface
public void someMethod(String jsCallbackCode) {
synchronized (mLock) {
mJsCallbackCode = jsCallbackCode;
}
// Start some business logic asynchronously, and return back here immediately.
return;
}
public void onBusinessLogicCompleted(bool success) {
String jsCallbackCode;
synchronized (mLock) {
jsCallbackCode = mJsCallbackCode;
}
mWebView.loadUrl("javascript:" + jsCallbackCode + "(" + success + ");void(0);");
}
在JavaScript中你可以这样使用它:
function callSomeMethod(callback) {
window._someMethodCallback = callback;
someService.someMethod(
'(function(success){' +
' if (success) window._someMethodCallback();' +
' delete window._someMethodCallback;' +
'})'
);
};
所以我的想法是你传递需要作为字符串回调的JS代码(因为你无法传递真正的JS对象)。此代码将在全局上下文中调用。
需要使用Java锁定,因为从JS调用的方法在专用线程上运行,而不是在应用程序的UI线程上运行。
请注意,在M预览中,已向WebView添加了postMessage
的API,从而能够在Java和JS代码之间发布异步消息。