Android WebView

时间:2015-06-13 07:45:34

标签: javascript android webview

我正在使用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代码?

1 个答案:

答案 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代码之间发布异步消息。