An Android bridge for sending messages between Java and JavaScript in WebView. and It is a mirror of marcuswestin/WebViewJavascriptBridge which supports IOS platforms.
This Android version project is a mirror of marcuswestin/WebViewJavascriptBridge , so there are some similarities between the two project , such as API design, native code, and the Javascript code is exactly the same.
-
Add the JitPack repository to your build file
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
-
Add the dependency
dependencies { compile 'com.github.wendux:WebViewJavascriptBridge:master-SNAPSHOT' }
See the wendu.jsbdemo/
folder. run the app
project and to see it in action.
To use a WebViewJavascriptBridge in your own project:
- Use
WVJBWebView
instead ofWebView
:
import wendu.webviewjavascriptbridge.WVJBWebView
...
WVJBWebView webView= (WVJBWebView) findViewById(R.id.webview);
- Register a handler in Java, and call a JS handler:
webView.registerHandler("Java Echo", new WVJBWebView.WVJBHandler() {
@Override
public void handler(Object data, WVJBWebView.WVJBResponseCallback callback) {
Log.d("wvjsblog","Java Echo called with: "+data.toString());
callback.onResult(data);
}
});
webView.callHandler("JS Echo", null, new WVJBWebView.WVJBResponseCallback() {
@Override
public void onResult(Object data) {
Log.d("wvjsblog","Java received response: "+data.toString());
}
});
- Copy and paste
setupWebViewJavascriptBridge
into your JS:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
- Finally, call
setupWebViewJavascriptBridge
and then use the bridge to register handlers and call Java handlers:
setupWebViewJavascriptBridge(function(bridge) {
/* Initialize your app here */
bridge.registerHandler('JS Echo', function(data, responseCallback) {
console.log("JS Echo called with:", data)
responseCallback(data)
})
bridge.callHandler('Java Echo', {'key':'value'}, function responseCallback(responseData) {
console.log("JS received response:", responseData)
})
})
Register a handler called handlerName
. The javascript can then call this handler with WebViewJavascriptBridge.callHandler("handlerName")
.
Example:
webView.registerHandler("getScreenHeight", new WVJBWebView.WVJBHandler() {
@Override
public void handler(Object data, WVJBWebView.WVJBResponseCallback callback) {
//wm is WindowManager
callback.onResult(wm.getDefaultDisplay().getHeight());
}
});
webView.registerHandler("log", new WVJBWebView.WVJBHandler() {
@Override
public void handler(Object data, WVJBWebView.WVJBResponseCallback callback) {
Log.d("wvjsblog","Log: "+data.toString());
}
});
Call the javascript handler called handlerName
. If a responseCallback
is given, the javascript handler can respond.
Example:
webview.callHandler("showAlert","Hi from Java to JS!");
webview.callHandler("getCurrentPageUrl", null, new WVJBWebView.WVJBResponseCallback() {
@Override
public void onResult(Object data) {
Log.d("wvjsblog","Current WVJBWebView page URL is: %@"+data.toString());
}
});
UNSAFE. Speed up bridge message passing by disabling the setTimeout safety check. It is only safe to disable this safety check if you do not call any of the javascript popup box functions (alert, confirm, and prompt). If you call any of these functions from the bridged javascript code, the app will hang.
Example:
webview.disableJavascriptAlertBoxSafetyTimeout(true);
Register a handler called handlerName
. The Java can then call this handler with webview callHandler("handlerName","Foo")
and webview.callHandler("handlerName", "Foo", new WVJBWebView.WVJBResponseCallback() {...})
Example:
bridge.registerHandler("showAlert", function(data) { alert(data) })
bridge.registerHandler("getCurrentPageUrl", function(data, responseCallback) {
responseCallback(document.location.toString())
})
Call an Java handler called handlerName
. If a responseCallback
function is given the Java handler can respond.
Example:
bridge.callHandler("Log", "Foo")
bridge.callHandler("getScreenHeight", null, function(response) {
alert('Screen height:' + response)
})
Calling bridge.disableJavascriptAlertBoxSafetyTimeout(...)
has the same effect as calling webview disableJavscriptAlertBoxSafetyTimeout(...)
in Java.
Example:
//disable
bridge.disableJavascriptAlertBoxSafetyTimeout()
//enable
bridge.disableJavascriptAlertBoxSafetyTimeout(false)
In this Android version, I have added a way to judge whether the handler (Javascript and java) exists.
In Java
webview.hasJavascriptMethod(String handlerName, WVJBMethodExistCallback callback)
For example:
webView.hasJavascriptMethod("echoHandler", new WVJBWebView.WVJBMethodExistCallback() {
@Override
public void onResult(boolean exist) {
if(exist) {
Log.d("wvjsblog", "Javascript handler 'echoHandler' exist. ");
}
}
});
In Javascript
bridge.hasNativeMethod("handlerName",function responseCallback(responseData){...})
For example:
bridge.hasNativeMethod('javaEchoToJs',function(exist){
if(exist){
console.log("Native method 'javaEchoToJs' exist! ")
}
})