有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javascript如何从webView返回值。评估JavaScript回调?

因此,我有一个名为JavascriptBridge的类,用于在Java和Javascript之间进行通信

要向javascript发送命令,我只需使用以下命令:

public void sendDataToJs(String command) {
    webView.loadUrl("javascript:(function() { " + command + "})()");
}

我的问题是,我还需要一个从Javascript返回响应的函数。我尝试使用webView。evaluateJavascript,但它跳过回调,因为evaluateJavascript是在另一个线程上完成的

public String getDataFromJs(String command, WebView webView) {
    String data = null;

    webView.evaluateJavascript("(function() { return " + command + "; })();", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String s) {
            Log.d("LogName", s); // Print "test"
            // data = s; // The value that I would like to return
        }
    });

    return data; // Return null, not "test"
}

对方法的调用:

String result = getDataFromJs("test", webView); // Should return "test" from the webView

我也尝试过使用@JavascriptInterface,但它给出了相同的结果


共 (2) 个答案

  1. # 1 楼答案

    我用Kotlin编写了一个小代码片段,可以帮助您。我是用RxKotlin写的,但是如果你使用Java,你可以使用RxJava2,因为它们是一样的

    fun getDataFromJsSync(command: String, webView: WebView): String {
        return getDataFromJs(command, webView).blockingGet()
    }
    
    fun getDataFromJs(command: String, webView: WebView): Single<String> {
        return Single.create { emitter: SingleEmitter<String> ->
            try {
                webView.evaluateJavascript(
                        "(function() { return $command; })();",
                        { result -> emitter.onSuccess(result) }
                )
            } catch (e: Exception) {
                emitter.onError(e)
            }
        }
    }
    

    另外,我还没有测试这些函数,也不能保证它们能正常工作,但我没有时间,我会在有时间的时候测试它们,并用Java重写它们,可能最多5个小时

  2. # 2 楼答案

    在Android上(即在当前线程上)没有同步评估Javascript的方法,所以最好使用evaluateJavascript,然后等待回调:

    public void getDataFromJs(String command, WebView webView) {
        webView.evaluateJavascript("(function() { return " + command + "; })();", new ValueCallback<String>() {
            @Override
            public void onReceiveValue(String s) {
                returnDataFromJs(s);
            }
        });
    }
    
    public returnDataFromJs(String data) {
        // Do something with the result.
    }
    

    没有方法在当前线程上评估Javascript,因为Javascript操作可能需要一段时间(JS引擎需要时间启动),这可能会阻止当前线程