【发布时间】: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