Android同步Javascript与棒棒糖上的WebView

Android Synchronous Javascript with WebView on Lollipop

本文关键字:WebView 棒棒糖 同步 Javascript Android      更新时间:2023-09-26

使用从http://www.gutterbling.com/blog/synchronous-javascript-evaluation-in-android-webview/我们已经成功地在我们的应用程序中实现了许多功能,这些功能允许我们的Android应用程序从Webview同步获取数据。

下面是gutterbling的例子:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.util.Log;
import android.webkit.WebView;

/**
 * Provides an interface for getting synchronous javascript calls
 * @author btate
 *
 */
public class SynchronousJavascriptInterface {
/** The TAG for logging. */
private static final String TAG = "SynchronousJavascriptInterface";
/** The javascript interface name for adding to web view. */
private final String interfaceName = "SynchJS";
/** Countdown latch used to wait for result. */
private CountDownLatch latch = null;
/** Return value to wait for. */
private String returnValue;
/**
 * Base Constructor.
 */
public SynchronousJavascriptInterface() {
}

/**
 * Evaluates the expression and returns the value.
 * @param webView
 * @param expression
 * @return
 */
public String getJSValue(WebView webView, String expression)
{
    latch = new CountDownLatch(1); 
    String code = "javascript:window." + interfaceName + ".setValue((function(){try{return " + expression
        + "+'"'";}catch(js_eval_err){return '';}})());";    
    webView.loadUrl(code);
    try {   
                    // Set a 1 second timeout in case there's an error
        latch.await(1, TimeUnit.SECONDS);
        return returnValue;
    } catch (InterruptedException e) {
        Log.e(TAG, "Interrupted", e);
    }
    return null;
}

/**
 * Receives the value from the javascript.
 * @param value
 */
public void setValue(String value)
{
    returnValue = value;
    try { latch.countDown(); } catch (Exception e) {} 
}
/**
 * Gets the interface name
 * @return
 */
public String getInterfaceName(){
    return this.interfaceName;
    }
}

这个JS接口是这样使用的:

WebView webView = new WebView(context);
SynchronousJavascriptInterface jsInterface = new jsInterface();
webView.addJavascriptInterface(jsInterface, jsInterface.getInterfaceName());
String jsResult = jsInterface.getJSValue(webView, "2 + 5");

尽管在Android 4.0-4.4.4中运行良好,但这对我们的Android 5.0(棒棒糖)不起作用。

在棒棒糖中,JS似乎在锁存倒计时完成后执行,而之前它会在倒计时完成前返回一个值。

Web视图中JS执行的线程有什么变化吗?有没有什么方法可以在不重写我们应用程序中依赖于能够同步调用JS的大块内容的情况下解决这个问题?

 loadUrl("javascript:" + code)

不要使用API>19,而是使用:

 evaluateJavascript(code, null);

或者,您也可以改进代码,使用evaluatteJavascript提供的回调。