无法在两个 WebView 之间进行通信
Unable to communicate between two WebViews
为了解释我想要实现的目标,我写下了我能够做的事情,然后 - 当出现问题时。什么效果好:
1) 我有 webView1
包含在加载的 HTML
<button onclick="android.buttonPressed();">Click</button>
绑定接口:
private class WebAppInterface1 {
Context context;
WebAppInterface1(Context c) {
context = c;
}
@JavascriptInterface
public void buttonPressed() {
Toast.makeText(context, "buttonPressed", Toast.LENGTH_LONG).show();
}
}
HTML 按钮有效。
2) 我有 webView2
包含在加载的 HTML
<script>
function f() {
document.write("bla bla bla");
}
</script>
那我打电话给
webView2.loadUrl("javascript:f();");
在 android 代码中,它也可以工作。
现在我想通过按 webView1
中的按钮修改 webView2
的页面。从技术上讲,这意味着当 JS 界面检测到 webView1
中的点击时,我想在 webView2
中调用 f()
。所以我添加了这一行
webView2.loadUrl("javascript:f();");
in buttonPressed()
JS 接口中的函数。但它没有效果。什么会导致问题?连接这些接收方和发送方是否有任何限制?也许我错过了一些设置或权限?
这是我的项目文件,我尽量使它们尽可能简单:layout, html, java。没有编辑其他文件。如果需要,可以提供任何其他信息。
我知道我的问题与另一个问题有关:无法从非主线程更新UI(在 SO here and here).但就我而言,由于某种原因没有任何错误。可能是因为 Java脚本不像 Java 那样 "strict"。
所以通过在我的 activity class 中添加 android.os.Handler
,在 onCreate
函数中分配它来解决:
handler = new Handler() {
public void handleMessage(Message msg) {
webView2.loadUrl("javascript:f()");
}
}
并在 buttonPressed
函数中访问它:
handler.obtainMessage(1).sendToTarget();
P.S。另一种方法是通过 Runnable
和调用 runOnUiThread(runnable)
来包装调用 webView2.loadUrl("javascript:f()");
。它看起来更整洁:
webView1.addJavascriptInterface(new Object() {
@JavascriptInterface
public void buttonPressed() {
runOnUiThread(new Runnable() {
@Override
public void run() {
webView2.loadUrl("javascript:f()");
}
});
}
}, "android");
P.P.S。 Enabling Java 8 in app/build.gradle
允许写得更整洁:
runOnUiThread(()->{webView2.loadUrl("javascript:f()");});
为了解释我想要实现的目标,我写下了我能够做的事情,然后 - 当出现问题时。什么效果好:
1) 我有 webView1
包含在加载的 HTML
<button onclick="android.buttonPressed();">Click</button>
绑定接口:
private class WebAppInterface1 {
Context context;
WebAppInterface1(Context c) {
context = c;
}
@JavascriptInterface
public void buttonPressed() {
Toast.makeText(context, "buttonPressed", Toast.LENGTH_LONG).show();
}
}
HTML 按钮有效。
2) 我有 webView2
包含在加载的 HTML
<script>
function f() {
document.write("bla bla bla");
}
</script>
那我打电话给
webView2.loadUrl("javascript:f();");
在 android 代码中,它也可以工作。
现在我想通过按 webView1
中的按钮修改 webView2
的页面。从技术上讲,这意味着当 JS 界面检测到 webView1
中的点击时,我想在 webView2
中调用 f()
。所以我添加了这一行
webView2.loadUrl("javascript:f();");
in buttonPressed()
JS 接口中的函数。但它没有效果。什么会导致问题?连接这些接收方和发送方是否有任何限制?也许我错过了一些设置或权限?
这是我的项目文件,我尽量使它们尽可能简单:layout, html, java。没有编辑其他文件。如果需要,可以提供任何其他信息。
我知道我的问题与另一个问题有关:无法从非主线程更新UI(在 SO here and here).但就我而言,由于某种原因没有任何错误。可能是因为 Java脚本不像 Java 那样 "strict"。
所以通过在我的 activity class 中添加 android.os.Handler
,在 onCreate
函数中分配它来解决:
handler = new Handler() {
public void handleMessage(Message msg) {
webView2.loadUrl("javascript:f()");
}
}
并在 buttonPressed
函数中访问它:
handler.obtainMessage(1).sendToTarget();
P.S。另一种方法是通过 Runnable
和调用 runOnUiThread(runnable)
来包装调用 webView2.loadUrl("javascript:f()");
。它看起来更整洁:
webView1.addJavascriptInterface(new Object() {
@JavascriptInterface
public void buttonPressed() {
runOnUiThread(new Runnable() {
@Override
public void run() {
webView2.loadUrl("javascript:f()");
}
});
}
}, "android");
P.P.S。 Enabling Java 8 in app/build.gradle
允许写得更整洁:
runOnUiThread(()->{webView2.loadUrl("javascript:f()");});