代理功能支持
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.
}
}
};