代理功能支持
if (WebViewFeature.isFeatureSupported(WebViewFeature.PROXY_OVERRIDE)) {
ProxyConfig proxyConfig = new ProxyConfig.Builder()
.addProxyRule("localhost:7890") //添加要用于所有 URL 的代理
.addProxyRule("localhost:1080") //优先级低于第一个代理,仅在上一个失败时应用
.addDirect() //当前面的代理失败时,不使用代理直连
.addBypassRule("baidu.com") //该网址不使用代理,直连服务
.addBypassRule("*.cn") //以.cn结尾的网址不使用代理
.build();
Executor executor = ...
Runnable listener = ...
ProxyController.getInstance().setProxyOverride(proxyConfig, executor, listener);
}
白名单代理
安全的 WebView 和 Native 通信支持
// App (in Java)
WebMessageListener myListener = new WebMessageListener() {
@Override
public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
boolean isMainFrame, JavaScriptReplyProxy replyProxy) {
// do something about view, message, sourceOrigin and isMainFrame.
replyProxy.postMessage("Got it!");
}
};
HashSet<String> allowedOriginRules = new HashSet<>(Arrays.asList("[https:\/\/example.com](https:\/\/example.com/ "https:\/\/example.com")"));
// Add WebMessageListeners.
WebViewCompat.addWebMessageListener(webView, "replyObject", allowedOriginRules,myListener);
调用上述方法之后,在 JavaScript 上下文中我们就可以访问 myObject,调用 postMessage 就可以回调 Native 端的 onPostMessage 方法并自动切换到主线程执行,当 Native 端需要发送消息给 WebView 时,可以通过 JavaScriptReplyProxy.postMessage 发送到 WebView,并将消息传递给 onmessage 闭包。
// Web page (in JavaScript)
myObject.onmessage = function(event) {
// prints "Got it!" when we receive the app's response.
console.log(event.data);
}
myObject.postMessage("I'm ready!");
文件传递
// App (in Java)
WebMessageListener myListener = new WebMessageListener() {
@Override
public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
boolean isMainFrame, JavaScriptReplyProxy replyProxy) {
// Communication is setup, send file data to web.
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER)) {
// Suppose readFileData method is to read content from file.
byte[] fileData = readFileData("myFile.dat");
replyProxy.postMessage(fileData);
}
}
}
// Web page (in JavaScript)
myObject.onmessage = function(event) {
if (event.data instanceof ArrayBuffer) {
const data = event.data; // Received file content from app.
const dataView = new DataView(data);
// Consume file content by using JavaScript DataView to access ArrayBuffer.
}
}
myObject.postMessage("Setup!");
WebView 传递文件给 Native:
// Web page (in JavaScript)
const response = await fetch('example.jpg');
if (response.ok) {
const imageData = await response.arrayBuffer();
myObject.postMessage(imageData);
}
// App (in Java)
WebMessageListener myListener = new WebMessageListener() {
@Override
public void onPostMessage(WebView view, WebMessageCompat message, Uri sourceOrigin,
boolean isMainFrame, JavaScriptReplyProxy replyProxy) {
if (message.getType() == WebMessageCompat.TYPE_ARRAY_BUFFER) {
byte[] imageData = message.getArrayBuffer();
// do something like draw image on ImageView.
}
}
};