在Lollipop上使用WebView的Android同步Javascript

Mik*_*ker 2 javascript android android-webview

使用从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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这个JS接口使用如下:

WebView webView = new WebView(context);
SynchronousJavascriptInterface jsInterface = new jsInterface();
webView.addJavascriptInterface(jsInterface, jsInterface.getInterfaceName());

String jsResult = jsInterface.getJSValue(webView, "2 + 5");
Run Code Online (Sandbox Code Playgroud)

尽管在Android 4.0 - 4.4.4中运行良好,但这对我们Android 5.0(Lollipop)并不适用.

似乎在Lollipop中,JS在锁定倒计时完成后执行,而之前它将在倒计时完成之前返回一个值.

Webview中的JS执行的线程有什么变化吗?有没有什么方法可以解决这个问题,而无需重新编写依赖于能够同步调用JS的大块应用程序?

小智 6

 loadUrl("javascript:" + code)
Run Code Online (Sandbox Code Playgroud)

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

 evaluateJavascript(code, null);
Run Code Online (Sandbox Code Playgroud)

或者,您可以改进代码以使用evaluateJavascript提供的回调.