creator-webview与Android交互
使用 WebView.evaluateJavascript
执行 js 代码
String callStr = String.format("window['java2js'](`%s`, `%s`)", funcName, jsonMsg);
WebViewIns.evaluateJavascript(callStr, null);
如果要透传数据结构或 json, 最好用 base64 加密一下, 然后在 js 中再解密出来, 以保证这些数据不会破会 js 代码的结构
一般跨语言的交互中, 我都会使用 base64 去加密数据使之变成正常的字符串
使用 WebView.addJavascriptInterface(Object, String);
映射对象和方法到 js 中一个变量, 例如:
public static class JsUtils {
@JavascriptInterface
public void call(String funcName, String jsonMsg) { // 具体多少个参数对上 js 即可
...
}
}
WebViewIns.addJavascriptInterface(new JsUtils(), "gJavaObj");
直接使用 gJavaObj 对象即可
gJavaObj.call(funcName, jsonMsg);
使用 WebView.loadUrl
String bdg = "js 代码";
WebView.loadUrl("javascript:" + bdg);
js 代码书写有严格的要求, 例如:
// 1. 一定要以这种 执行方法 的方式初始化
// 2. 语句结尾要加 ;, 不然报错 Invalid left-hand side expression in postfix operation
// 3. 注释必须清楚掉
(function() {
window.cm = {};
window.java2js = function(f, m) {
var oldCb = window.cm[f];
if (oldCb) oldCb(window.atob(m));
window.cm[f] = null;
};
window.WebViewJavascriptBridge = {
init: function() { },
registerHandler: function() { },
callHandler: function(f, m, c) {
window.cm[f] = c;
gJavaObj.call(f, m);
},
};
document.dispatchEvent(new Event("WebViewJavascriptBridgeReady"));
})()
可以使用 uglyjs 把代码压缩成一行
String bdg = "window.cm={},window.java2js=function(f,m){var oldCb=window.cm[f];oldCb&&oldCb(window.atob(m)),window.cm[f]=null},window.WebViewJavascriptBridge={init:function(){},registerHandler:function(){},callHandler:function(f,m,c){window.cm[f]=c,gJavaObj.call(f,m)}},document.dispatchEvent(new Event(\"WebViewJavascriptBridgeReady\"));"
代码
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.net.http.SslError;
import android.util.Base64;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class WebviewHelper {
public static WebviewHelper instance = null;
private RelativeLayout mLayoutRoot;
private WebView mWebview;
private static Map<String, BridgeHandler> mJsCb = new HashMap<>();
public static void showWebview(final Activity activity, final String url, final ActivityMgr.CodeRunnable task) {
closeWebview(activity, () -> {
instance = new WebviewHelper();
instance.show(activity, url);
if (task != null) {
task.run(ActivityMgr.Ok, "");
}
});
}
public static void closeWebview(final Activity activity, final Runnable task) {
activity.runOnUiThread(() -> {
if (instance != null) {
instance.destroy();
}
if (task != null) {
task.run();
}
});
}
public static boolean goBack() {
ActivityMgr.Act.moveTaskToBack(true);
return false;
}
@SuppressLint("SetJavaScriptEnabled")
public void show(Activity activity, final String url) {
final RelativeLayout rLayout = new RelativeLayout(activity);
mLayoutRoot = rLayout;
RelativeLayout.LayoutParams rParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
final WebView wv = new WebView(activity);
wv.setWebViewClient(new WebviewClientHelper());
mWebview = wv;
wv.setLayoutParams(lParams);
rLayout.addView(wv);
activity.addContentView(rLayout, rParams);
mWebview.addJavascriptInterface(new JsUtils(), "gJavaObj");//AndroidtoJS类对象映射到js的test对象
wv.loadUrl(url);
// 设置webview
WebSettings settings = wv.getSettings();
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); // 有缓存就使用缓存
settings.setSupportZoom(false);
settings.setBuiltInZoomControls(true);
}
public static void regHandler(String name, BridgeHandler bh) {
mJsCb.put(name, bh);
}
private void destroy() {
if (mWebview != null) {
mWebview.destroy();
mWebview = null;
}
if (mLayoutRoot != null) {
ViewGroup vg = (ViewGroup) mLayoutRoot.getParent();
vg.removeView(mLayoutRoot);
mLayoutRoot = null;
}
instance = null;
}
public interface BridgeHandler {
void handler(String var1, Consumer<String> var2);
}
public static class JsUtils {
@JavascriptInterface
public void call(String funcName, String jsonMsg) {
BridgeHandler bh = mJsCb.get(funcName);
if (bh == null) {
ActivityMgr.E("no func: %s", funcName);
return;
}
bh.handler(jsonMsg, (result) -> {
try {
// 交互是需要 base64 处理一下
result = Base64.encodeToString((result != null ? result : "").getBytes(StandardCharsets.UTF_8), Base64.DEFAULT);
String callStr = String.format("window['java2js'](`%s`, `%s`)", funcName, result);
instance.mWebview.evaluateJavascript(callStr, null);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
public static class WebviewClientHelper extends WebViewClient {
public boolean isLoadBdg = false;
@Override
public void onPageFinished(WebView view, String url) {
if (!isLoadBdg) {
String bdg = "window.cm={},window.java2js=function(f,m){var oldCb=window.cm[f];oldCb&&oldCb(window.atob(m)),window.cm[f]=null},window.WebViewJavascriptBridge={init:function(){},registerHandler:function(){},callHandler:function(f,m,c){window.cm[f]=c,gJavaObj.call(f,m)}},document.dispatchEvent(new Event(\"WebViewJavascriptBridgeReady\"));";
view.loadUrl("javascript:" + bdg);
isLoadBdg = true;
}
super.onPageFinished(view, url);
}
}
}
代码
<!DOCTYPE html>
<html>
<head>
<script>
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
console.log("--- WebViewJavascriptBridgeReady");
},
false
);
function js2java() {
console.log("--- js2java");
// gJavaObj.hello("Hello Terry")
var funcName = "StartInfo"
var jsonMsg = "World 002"
window.WebViewJavascriptBridge.callHandler(funcName, jsonMsg, function(responseData) {
console.log("--- responseData:", responseData);
})
}
console.log("--- web loaded");
</script>
<title>Test Webview</title>
</head>
<body>
<div id="mydiv">
<br /><br /><button onclick="js2java()"> js2java </button>
</div>
</body>
</html>
更多【python-creator-webview与Android交互】相关视频教程:www.yxfzedu.com