【问题标题】:Android Synchronous Javascript with WebView on LollipopAndroid 同步 Javascript 与 Lollipop 上的 WebView
【发布时间】:2014-10-28 11:05: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 (Lollipop) 中。

看起来好像在 Lollipop 中,JS 在闩锁倒计时完成后执行,而之前它会在倒计时完成之前返回一个值。

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

【问题讨论】:

    标签: javascript android android-webview


    【解决方案1】:
     loadUrl("javascript:" + code)
    

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

     evaluateJavascript(code, null);
    

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

    【讨论】:

    • 嗯,它不起作用。请参阅code.google.com/p/android/issues/detail?id=79924 我希望它会被修复,但现在没有解决方法。有什么想法吗?
    • @RomanZhukov 感谢您提供指向该问题的链接,从更改日志看来,此问题已在 Android 5.1(以及即将发布的 Webview 40 版本中)中修复,我尚未测试我的旧版本应用程序来验证这一事实,但会这样做。
    • @MikeFosker 你有没有让这个正常工作?我遇到了一个非常相似的问题,我无法解决。 stackoverflow.com/questions/37475073/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多