【问题标题】:Asynchronous JavaScript calls from Android WebView来自 Android WebView 的异步 JavaScript 调用
【发布时间】:2015-06-13 07:45:34
【问题描述】:

我正在使用 WebView 构建混合 Android 应用程序,该应用程序使用 JavaScriptInterface 注释与设备通信

从 Web 视图:

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();
    })
};

最好使用promise:

function callSomeMethod() {
    return someService.someMethod()
    //someMethod returns promise
};

Android WebView 是否内置了对异步运行 JavaScript 代码的支持?

【问题讨论】:

    标签: javascript android webview


    【解决方案1】:

    这完全取决于你。您只需要立即从注入的方法返回,但可以在执行完成后调用 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 预览版中,postMessage 的 API 已添加到 WebView,可以在 Java 和 JS 代码之间发布异步消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多