Javascript 接口回调在 android webview 中不起作用 API >= 21 with GWT 2.7 javascript
Javascript interface Callback not working in android webview API >= 21 with GWT 2.7 javascript
我的代码遇到了一个特殊问题。 java脚本回调在 api 级别 19 或更低的设备上工作,但它 在 API 21 及更高级别 上不工作。异常正常的 Html java 脚本回调在所有 API 级别上都有效。我没有使用混淆器。这是我的代码:
MainActivity.java
WebAppInterface wai = new WebAppInterface(this, this);
myWebView.addJavascriptInterface(wai, "Android");
myWebView.loadUrl("http://192.168.2.246/abhishek/test/");
WebAppInterface.java
class WebAppInterface {
Context mContext;
MainActivity parent;
/** Instantiate the interface and set the context */
WebAppInterface(Context c, MainActivity parent) {
mContext = c;
this.parent = parent;
}
@JavascriptInterface
public void setHeading(String heading) {
Toast.makeText(mContext, "Setting heading to " + heading, Toast.LENGTH_SHORT).show();
}
}
GWT 代码:
java脚本:
function setHeading(heading) {
console.log("setting heading...");
// Android callback
if(typeof Android !== 'undefined'){
Android.setHeading(heading);
}
if(typeof Android == 'undefined') {
console.log("undefined!!");
}
}
java:
public static final native void setAppHeading(String heading) /*-{
$wnd.setHeading(heading);
}-*/;
我在 lollipop 及更高版本上得到 typeof Android as 'undefined'。任何人都可以告诉我这有什么问题或给我一个 GWT java 脚本的示例代码,适用于 Android API 21 级及更高级别。
超时延迟似乎可以解决问题。我不知道怎么做,但它有效。
public static final native void setAppHeading(String heading) /*-{
setTimeout(function() {$wnd.setHeading(heading);}, 3000);
}-*/;
原来回调对象附加在 window 级别并且 javascript 代码在 GWT 创建的内部 iFrame 中执行。
public static final native void setAppHeading(String heading) /*-{
if(typeof $wnd.Android !== 'undefined'){
$wnd.Android.setHeading(heading);
return;
}
}-*/;
所以这段代码有效。
可能是竞争条件?您可能想将它放在计时器中以确保它不是。
更新:
因为这确实是一个竞争条件,将计时器设置为 1 毫秒可能就足够了,使用以下可能是最佳实践:
Scheduler.scheduleDeferred
见http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsDelayed.html
我的代码遇到了一个特殊问题。 java脚本回调在 api 级别 19 或更低的设备上工作,但它 在 API 21 及更高级别 上不工作。异常正常的 Html java 脚本回调在所有 API 级别上都有效。我没有使用混淆器。这是我的代码:
MainActivity.java
WebAppInterface wai = new WebAppInterface(this, this);
myWebView.addJavascriptInterface(wai, "Android");
myWebView.loadUrl("http://192.168.2.246/abhishek/test/");
WebAppInterface.java
class WebAppInterface {
Context mContext;
MainActivity parent;
/** Instantiate the interface and set the context */
WebAppInterface(Context c, MainActivity parent) {
mContext = c;
this.parent = parent;
}
@JavascriptInterface
public void setHeading(String heading) {
Toast.makeText(mContext, "Setting heading to " + heading, Toast.LENGTH_SHORT).show();
}
}
GWT 代码:
java脚本:
function setHeading(heading) {
console.log("setting heading...");
// Android callback
if(typeof Android !== 'undefined'){
Android.setHeading(heading);
}
if(typeof Android == 'undefined') {
console.log("undefined!!");
}
}
java:
public static final native void setAppHeading(String heading) /*-{
$wnd.setHeading(heading);
}-*/;
我在 lollipop 及更高版本上得到 typeof Android as 'undefined'。任何人都可以告诉我这有什么问题或给我一个 GWT java 脚本的示例代码,适用于 Android API 21 级及更高级别。
超时延迟似乎可以解决问题。我不知道怎么做,但它有效。
public static final native void setAppHeading(String heading) /*-{
setTimeout(function() {$wnd.setHeading(heading);}, 3000);
}-*/;
原来回调对象附加在 window 级别并且 javascript 代码在 GWT 创建的内部 iFrame 中执行。
public static final native void setAppHeading(String heading) /*-{
if(typeof $wnd.Android !== 'undefined'){
$wnd.Android.setHeading(heading);
return;
}
}-*/;
所以这段代码有效。
可能是竞争条件?您可能想将它放在计时器中以确保它不是。
更新:
因为这确实是一个竞争条件,将计时器设置为 1 毫秒可能就足够了,使用以下可能是最佳实践:
Scheduler.scheduleDeferred
见http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsDelayed.html