对的WebView和本地之间的通信替代方法 [英] Alternative way for communication between WebView and native
问题描述
我使用的WebView
在我的本机应用程序有很多的JavaScript。如果JS一边要调用本地函数这是相当流畅使用 JavaScriptInterface
。但是,如果原生要调用JS功能,它不是那么容易的。我试过两个解决方案迄今:
I am using WebView
and a lot of JavaScript in my native application. If JS side wants to call native functions it's rather smooth using JavaScriptInterface
. However, if native wants to call JS function it's not so easy. I've tried two solutions so far:
- 调用
使用loadURL
法的javascript:东西()
URL - 当用户在键盘上打字的东西,因为不能接受的WebView
在功能执行后隐藏它 - 询问机端的功能,每x秒($ P $由
字符串
对象psented)和
叫的eval()
上一个结果 - 有时是1秒钟我得到50-60秒后,这些请求设定的时间间隔后!
- calling
loadUrl
method withjavascript:something()
URL - not acceptable since when user is typing something on keyboardWebView
is hiding it after function execution - asking native side for functions every x seconds (presented by
String
object) and calleval()
on a result - sometimes after setting interval for 1 seconds I was getting those requests after 50-60 seconds!
我想知道是否有任何其他方式来完成这种通信模式。比方说,建立内部的应用程序的本地插座
/ HTTP
/东西,别的服务器并给<$ C $它访问C>的WebView 。我在寻找任何提示如何(如果可能的话)做到这一点。
I am wondering if there's any other way to accomplish this communication model. Let's say create local Socket
/HTTP
/something-else server inside app and give access for it to WebView
. I am looking for any tips how (if it's possible) do that.
推荐答案
我有以下的code,它使用Java反射从Java调用JavaScript。它避免以下的错误使用loadURL:
1.使用loadURL可能隐藏键盘时,你的焦点在输入。
2.使用loadURL不能称之为过于频繁。
I have the following code which uses java reflection to call JavaScript from Java. It avoids the following loadUrl bugs: 1. loadUrl may hide keyboard when your focus in a input. 2. loadUrl cannot be called too often.
希望这有助于:
public class AdvancedWebView extends WebView {
private static final int EXECUTE_JS = 194;
Method sendMessageMethod;
Object webViewCore;
boolean initFailed = false;;
InputMethodManager imm;
public AdvancedWebView(Context context, AttributeSet attrs) {
super(context, attrs);
imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
this.getSettings().setJavaScriptEnabled(true);
this.initReflection();
}
@SuppressWarnings("rawtypes")
private void initReflection() {
Object webViewObject = this;
Class webViewClass = WebView.class;
try {
Field f = webViewClass.getDeclaredField("mProvider");
f.setAccessible(true);
webViewObject = f.get(this);
webViewClass = webViewObject.getClass();
} catch (Throwable e) {
// mProvider is only required on newer Android releases.
}
try {
Field f = webViewClass.getDeclaredField("mWebViewCore");
f.setAccessible(true);
webViewCore = f.get(webViewObject);
if (webViewCore != null) {
sendMessageMethod = webViewCore.getClass().getDeclaredMethod("sendMessage", Message.class);
sendMessageMethod.setAccessible(true);
System.out.println("sendMessageMethod-----"+sendMessageMethod);
}
hasIntercepted = true;
} catch (Throwable e) {
hasIntercepted = false;
//Log.e(LOG_TAG, "PrivateApiBridgeMode failed to find the expected APIs.", e);
}finally{
if(sendMessageMethod == null)
{
hasIntercepted = false;
}
}
}
private void loadJs(String url) {
if (sendMessageMethod == null && !initFailed) {
initReflection();
}
// webViewCore is lazily initialized, and so may not be available right away.
if (sendMessageMethod != null) {
//String js = popAndEncodeAsJs();
Message execJsMessage = Message.obtain(null, EXECUTE_JS, url);
try {
sendMessageMethod.invoke(webViewCore, execJsMessage);
} catch (Throwable e) {
//Log.e(LOG_TAG, "Reflection message bridge failed.", e);
}
}
}
}
这篇关于对的WebView和本地之间的通信替代方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!