WebView与JavaScriptBridge的基本使用方式
MIILN 2024-07-09 14:33:01 阅读 69
一、WebView
在移动应用程序中用来显示网页内容的组件,相当于内嵌浏览器
1.Webkit
开源的网页浏览引擎,Chrome和Safari浏览器的渲染内核
WebKit Embedding API:浏览器UI与 WebKit 引擎进行交互的接口
WebCore:网页内容渲染
JSCore:解释和执行JS代码,实现动态网页内容的更新和交互
Platform API:与特定操作系统和平台进行通信和交互
2.WebView
主要作用:显示网页内容,提供了加载URL、生命周期管理、状态管理、调用JS代码等功能
常用方法:
加载网页:loadUrl(String url)
管理浏览历史:goBack()、goForward()控制页面回退和前进
获取辅助类:getSettings()、setWebViewClient(WebViewClient client)、setWebChromeClient(WebChromeClient client)
添加JS接口:addJavascriptInterface(Object object, String name)
执行JS代码:evaluateJavascript(String script, ValueCallback<String> resultCallback)
3.WebSettings
主要作用:配置和管理Webview
常用方法:
设置缓存模式:setCacheMode(int mode)
WebSettings.LOAD_DEFAULT:默认的缓存使用模式。根据cache-control头决定是否从网络加载数据。
WebSettings.LOAD_CACHE_ELSE_NETWORK:只要缓存可用,就加载缓存,即使它已经过期。如果缓存不可用,就从网络加载数据。
WebSettings.LOAD_NO_CACHE:不使用缓存,只从网络加载数据。
WebSettings.LOAD_CACHE_ONLY:只从缓存加载数据,不从网络加载数据。
启用或禁用JS交互:setJavaScriptEnabled(boolean flag)
启用地理位置:setGeolocationEnabled(boolean flag);
4.WebViewClient
主要作用:处理通知、请求、加载错误等事件
常用方法:
拦截 URL 加载请求,有回调,允许应用自行处理特定的 URL
shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
拦截和处理资源请求,有回调,可以返回一个 WebResourceResponse 对象来替代原始请求的响应
shouldInterceptRequest(WebView view, WebResourceRequest request)
页面开始加载时调用,通知作用,无回调
onPageStarted(WebView view, String url, Bitmap favicon)
页面加载完成时调用,通知作用,无回调
onPageFinished(WebView view, String url)
加载资源时调用,通知作用,无回调
onLoadResource(WebView view, String url)
5.WebChromeClient
主要作用:辅助WebView处理JS相关事件及浏览器UI元素变化
常用方法:
页面需要访问某些敏感资源时,处理权限请求
onPermissionRequest(final PermissionRequest request)
麦克风:PermissionRequest.RESOURCE_AUDIO_CAPTURE
摄像头:PermissionRequest.RESOURCE_VIDEO_CAPTURE
定位权限
onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback)
origin:请求权限的网页的原始URL
callback:处理权限请求的回调接口
onProgressChanged(WebView view, int newProgress):页面加载进度发生变化时传递当前加载进度
onReceivedTitle(WebView view, String title):页面的标题发生变化时传递新的页面标题
onJsAlert(WebView view, String url, String message, JsResult result):传递 alert 提示框的信息和结果处理对象
onJsConfirm(WebView view, String url, String message, JsResult result):传递 confirm 确认框的信息和结果处理对象
onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result):传递 prompt 输入框的信息、默认值和结果处理对象
二、JavaScriptBridge
将Native接口封装成JS接口,将JS接口封装成原生接口,构建Native和JS的双向通信通道
1.Android调用JS
使用WebView的evaluateJavascript()
在main目录下新建assets文件夹,将 html 文件放到 app/src/main/assets 目录下
<code><!DOCTYPE html>
<html>
<head>
<title>JS Bridge Example</title>
<style>
body, html {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
</style>
</head>
<body>
<button onclick="showAndroidSnackbar('此处调用Android.showSnackbar')">显示Snackbar</button>code>
<div id="messageContainer"></div>code>
<script type="text/javascript">code>
function showAndroidSnackbar(message) {
// 通过WebView得到接口对象Android,调用注解标注的方法
Android.showSnackbar(message);
}
function jsMethod(message) {
// 供Android调用的JS方法,传入message显示在屏幕上
var container = document.getElementById("messageContainer");
var p = document.createElement("p");
p.textContent = message;
container.appendChild(p);
}
</script>
</body>
</html>
在WebView中开放浏览器JS代码执行权限,调用JS方法,WebView自带JS解析器可以执行JS代码
public class WebActivity extends AppCompatActivity {
private WebView webView;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 创建WebView
setContentView(R.layout.activity_web);
webView = findViewById(R.id.webView);
// 启用JavaScript
webView.getSettings().setJavaScriptEnabled(true);
// 将Java对象暴露给JavaScript,并给对象指定一个名称
webView.addJavascriptInterface(new WebInterface(this), "Android");
// 在WebView中加载html页面
webView.loadUrl("file:///android_asset/H5_demo.html");
// 调用JS方法,页面加载后延迟三秒显示传入的文字
webView.postDelayed(() -> webView.evaluateJavascript("jsMethod('通过evaluateJavascript调用')", null), 3000);
}
}
2.JS调用Android
请求拦截:使用WebViewClient的shouldOverrideUrlLoading()、shouldInterceptRequest()
弹窗拦截:使用WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()
JS上下文注入:通过WebView提供的接口,向JS的全局Context(window)中注入对象,调用原生代码
在Android代码中创建一个JavaScript接口类,使用@JavascriptInterface注解标记需要暴露给JS的方法,用于处理来自H5页面的调用请求
public class WebInterface {
private final Context context;
WebInterface(Context context) {
this.context = context;
}
@JavascriptInterface
public void showSnackbar(final String message) {
if (context != null) {
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
View rootView = ((Activity) context).findViewById(android.R.id.content);
Snackbar.make(rootView, message, Snackbar.LENGTH_SHORT).show();
}
});
}
}
}
在Activity中设置WebView,并使用addJavascriptInterface将Java对象暴露给JavaScript,给对象指定一个名称
webView.addJavascriptInterface(new WebInterface(this), "Android");
在H5页面中编写JavaScript代码,通过接口调用Android方法
<script>
function showAndroidSnackbar(message) {
// 通过WebView得到接口对象Android,调用注解标注的方法
Android.showSnackbar(message);
}
</script>
WebView内部会解析JavaScript调用,找到对应的Java对象和方法,并将JavaScript传递的参数转换为Java方法的参数,调用该方法
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。