灵活的自定义 WebView 组件(新版本)

效果图:

1.1 什么是 MyWebViewNew

MyWebViewNew 是一个功能强大的自定义 WebView 组件,专为 Android 平台设计。它继承自原生 WebView,同时采用组合模式,提供了高度的灵活性和可扩展性。

1.2 设计理念

  1. 继承与组合并存:继承 WebView 保持 API 兼容性,同时使用组合模式实现灵活的配置

  2. 默认实现与自定义平衡:提供开箱即用的默认功能,同时允许完全自定义所有组件

  3. 动态配置支持:支持运行时修改配置,无需重新创建实例

  4. 生命周期管理:完整的生命周期管理,避免内存泄漏

  5. 渐进式使用:支持三种使用模式(简单、进阶、高级),适应不同场景

1.3 核心特性

  • ✅ 全屏视频播放:自动处理视频的全屏/退出全屏,支持横竖屏切换

  • ✅ 倍数播放控制:支持 0.5x - 2.0x 的播放速度调节

  • ✅ 文件下载功能:支持自定义下载逻辑或使用系统下载管理器

  • ✅ 页面导航控制:前进、后退、刷新、停止加载等完整的导航功能

  • ✅ 缓存和 Cookie 管理:灵活的缓存策略和 Cookie 管理

  • ✅ JavaScript 交互:内置 JavaScript 接口,支持双向通信

  • ✅ 自定义组件:支持自定义 WebViewClient、WebChromeClient、DownloadListener

  • ✅ 生命周期管理:完整的生命周期管理,避免内存泄漏

  • ✅ 错误处理:完善的错误处理和日志输出

  • ✅ 兼容性:支持 Android 4.4+ 版本


二、核心功能详解

2.1 全屏视频播放

2.1.1 功能描述

✅ 自动处理 HTML5 视频的全屏播放,包括:

  • 自动检测视频元素

  • ✅ 进入全屏时自动切换屏幕方向

  • ✅ 退出全屏时恢复原始屏幕方向

  • ✅ 支持横屏和竖屏视频自动识别

  • ✅ 支持自定义 WebChromeClient 时仍然保留全屏功能

2.1.2 技术实现
// 核心实现类 private class WebChromeClientWrapper extends WebChromeClient { private WebChromeClient customClient; public WebChromeClientWrapper(WebChromeClient customClient) { this.customClient = customClient; } @Override public void onShowCustomView(View view, CustomViewCallback callback) { // 处理全屏显示 enterFullScreen(view, callback); // 委托给自定义 WebChromeClient if (customClient != null) { customClient.onShowCustomView(view, callback); } } @Override public void onHideCustomView() { // 处理退出全屏 exitFullScreen(); // 委托给自定义 WebChromeClient if (customClient != null) { customClient.onHideCustomView(); } } }
2.1.3 关键方法
/** * 进入全屏模式 * @param view 全屏显示的视图(通常是视频播放器) * @param callback 退出全屏时的回调 */ private void enterFullScreen(View view, WebChromeClient.CustomViewCallback callback) /** * 退出全屏模式 */ private void exitFullScreen() /** * 设置屏幕方向 * @param orientation 目标屏幕方向 */ private void setScreenOrientation(int orientation)
2.1.4 配置要求

在 AndroidManifest.xml 中为 Activity 添加配置:

<activity android:name=".YourActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:screenOrientation="portrait"> </activity>

说明

  • orientation:屏幕方向变化时不重建 Activity

  • screenSize:屏幕尺寸变化时不重建 Activity(必须和 orientation 一起配置)

  • keyboardHidden:键盘显示/隐藏时不重建 Activity

如果没有配置,系统会输出警告日志并跳过屏幕方向设置,避免闪退。


2.2 倍数播放控制

2.2.1 功能描述

支持通过 JavaScript 接口控制视频的播放速度,范围为 0.5x - 2.0x。

2.2.2 技术实现
/** * JavaScript 接口类,用于与 JavaScript 交互 */ public class WebViewJavaScriptInterface { /** * 设置视频播放速度 * <p> * 此方法由 JavaScript 调用,用于设置视频的播放速度 * <p> * @param speed 播放速度(0.5 - 2.0) * - 0.5: 半速播放 * - 1.0: 正常速度 * - 2.0: 两倍速播放 */ @JavascriptInterface public void setPlaybackSpeed(double speed) { // 限制速度范围在 0.5 到 2.0 之间 if (speed < 0.5) { speed = 0.5; } else if (speed > 2.0) { speed = 2.0; } currentPlaybackSpeed = speed; Log.d(TAG, "JavaScript 设置播放速度: " + speed + "x"); // 通知外部监听器 if (onPlaybackSpeedChangeListener != null) { onPlaybackSpeedChangeListener.onPlaybackSpeedChange(speed); } } /** * 获取当前播放速度 * <p> * 此方法由 JavaScript 调用,用于获取当前的播放速度 * <p> * @return 当前播放速度(默认 1.0) */ @JavascriptInterface public double getPlaybackSpeed() { return currentPlaybackSpeed; } }
2.2.3 使用方式
// 设置播放速度 webView.setPlaybackSpeed(1.5); // 1.5倍速 // 获取当前播放速度 double speed = webView.getPlaybackSpeed(); // 监听播放速度变化 webView.setOnPlaybackSpeedChangeListener(new MyWebViewNew.OnPlaybackSpeedChangeListener() { @Override public void onPlaybackSpeedChange(double speed) { Log.d(TAG, "播放速度变为: " + speed + "x"); } });

2.3 文件下载功能

2.3.1 功能描述

支持 HTML5 文件下载,包括:

  • ✅ 自动检测下载链接

  • ✅ 支持自定义下载逻辑

  • ✅ 支持使用系统下载管理器

  • ✅ 支持下载通知和进度显示

  • ✅ 支持断点续传

2.3.2 技术实现
/** * 使用系统下载管理器下载文件 * <p> * 此方法使用 Android 系统的下载管理器进行下载 * <p> * 优点: * - 系统级下载,稳定可靠 * - 支持断点续传 * - 支持下载通知 * - 支持下载管理(查看、暂停、取消等) * <p> * 注意: * - 需要在 AndroidManifest.xml 中声明 INTERNET 权限 * - 对于 Android 6.0+,需要动态请求存储权限 * - 下载的文件会保存到系统默认下载目录(通常是 /sdcard/Download/) * @param url 下载链接 * @param fileName 文件名 */ private void startSystemDownload(String url, String fileName) { try { // 使用系统下载管理器 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { android.app.DownloadManager downloadManager = (android.app.DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE); // 创建下载请求 android.app.DownloadManager.Request request = new android.app.DownloadManager.Request(Uri.parse(url)); // 设置下载目录和文件名 request.setDestinationInExternalPublicDir( Environment.DIRECTORY_DOWNLOADS, fileName ); // 设置通知标题 request.setTitle(fileName); // 设置通知描述 request.setDescription("正在下载..."); // 设置通知可见性 request.setNotificationVisibility( android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED ); // 设置允许的网络类型(移动网络和 WIFI) request.setAllowedNetworkTypes( android.app.DownloadManager.Request.NETWORK_MOBILE | android.app.DownloadManager.Request.NETWORK_WIFI ); // 开始下载 long downloadId = downloadManager.enqueue(request); Log.d(TAG, "使用系统下载管理器下载: " + fileName); Log.d(TAG, "下载 ID: " + downloadId); Log.d(TAG, "保存路径: " + Environment.DIRECTORY_DOWNLOADS + "/" + fileName); } else { // Android 2.3 以下版本,使用 Intent.ACTION_VIEW Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); getContext().startActivity(intent); Log.d(TAG, "使用 Intent.ACTION_VIEW 下载: " + fileName); } } catch (Exception e) { Log.e(TAG, "系统下载失败: " + e.getMessage()); e.printStackTrace(); } }
2.3.3 使用方式
// 方式1:使用默认下载逻辑(系统下载管理器) webView.init(); // 默认使用系统下载管理器 // 方式2:自定义下载逻辑 webView.setOnDownloadListener(new MyWebViewNew.OnDownloadListener() { @Override public void onDownload(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { // 自定义下载逻辑 Log.d(TAG, "开始下载: " + url); Log.d(TAG, "文件类型: " + mimetype); Log.d(TAG, "文件大小: " + contentLength); // 可以选择: // 1. 使用自定义下载管理器 // 2. 显示下载对话框 // 3. 检查网络状态 // 4. 其他自定义处理 } });

2.4 页面导航控制

2.4.1 功能描述

提供完整的页面导航控制功能,包括:

  • 前进(goForward)

  • 后退(goBack)

  • 刷新(reload)

  • 停止加载(stopLoading)

  • 加载 URL(loadUrl)

  • 加载 HTML 内容(loadData)

2.4.2 核心方法
/** * 加载指定的 URL * <p> * 此方法会加载指定的 URL,并在加载完成后注入 JavaScript 接口 * <p> * @param url 要加载的 URL(必须以 http:// 或 https:// 开头) */ @Override public void loadUrl(String url) { Log.d(TAG, "加载 URL: " + url); super.loadUrl(url); } /** * 前进到下一页 * <p> * 如果可以前进,则前进到下一页 * <p> * @return 是否成功前进 */ public boolean goForward() { if (canGoForward()) { super.goForward(); Log.d(TAG, "前进到下一页"); return true; } else { Log.w(TAG, "无法前进,已经是最后一页"); return false; } } /** * 后退到上一页 * <p> * 如果可以后退,则后退到上一页 * <p> * @return 是否成功后退 */ public boolean goBack() { if (canGoBack()) { super.goBack(); Log.d(TAG, "后退到上一页"); return true; } else { Log.w(TAG, "无法后退,已经是第一页"); return false; } } /** * 刷新当前页面 * <p> * 重新加载当前页面的内容 */ public void reload() { Log.d(TAG, "刷新当前页面"); super.reload(); } /** * 停止加载当前页面 * <p> * 取消正在进行的页面加载 */ public void stopLoading() { Log.d(TAG, "停止加载当前页面"); super.stopLoading(); }

2.5 缓存和 Cookie 管理

2.5.1 功能描述

提供灵活的缓存策略和 Cookie 管理,包括:

  • 多种缓存模式选择

  • 缓存大小控制

  • Cookie 启用/禁用

  • Cookie 清除

2.5.2 缓存策略
// 缓存模式说明 // LOAD_DEFAULT: 默认模式,根据缓存有效期决定是否使用缓存 // LOAD_CACHE_ELSE_NETWORK: 优先使用缓存,没有缓存时才从网络加载 // LOAD_NO_CACHE: 不使用缓存,始终从网络加载 // LOAD_CACHE_ONLY: 只使用缓存,不从网络加载 /** * 设置缓存模式 * <p> * 控制 WebView 的缓存策略 * <p> * @param cacheMode 缓存模式 * - WebSettings.LOAD_DEFAULT: 默认模式 * - WebSettings.LOAD_CACHE_ELSE_NETWORK: 优先使用缓存 * - WebSettings.LOAD_NO_CACHE: 不使用缓存 * - WebSettings.LOAD_CACHE_ONLY: 只使用缓存 */ public void setCacheMode(int cacheMode) { this.cacheMode = cacheMode; Log.d(TAG, "设置缓存模式: " + cacheMode); } /** * 设置是否启用缓存 * <p> * 控制是否启用 WebView 的缓存功能 * <p> * @param enableCache 是否启用缓存 */ public void setEnableCache(boolean enableCache) { this.enableCache = enableCache; Log.d(TAG, "设置是否启用缓存: " + enableCache); } /** * 设置缓存大小(字节) * <p> * 控制 WebView 的最大缓存大小 * <p> * @param cacheSize 缓存大小(字节),默认 8MB */ public void setCacheSize(int cacheSize) { this.cacheSize = cacheSize; Log.d(TAG, "设置缓存大小: " + cacheSize + " bytes"); }
2.5.3 Cookie 管理
/** * 设置是否启用 Cookie * <p> * 控制是否启用 WebView 的 Cookie 功能 * <p> * @param enableCookies 是否启用 Cookie */ public void setEnableCookies(boolean enableCookies) { this.enableCookies = enableCookies; Log.d(TAG, "设置是否启用 Cookie: " + enableCookies); } /** * 清除所有 Cookie * <p> * 清除 WebView 中存储的所有 Cookie */ public void clearCookies() { CookieManager cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookies(null); cookieManager.flush(); Log.d(TAG, "清除所有 Cookie"); }

2.6 JavaScript 交互

2.6.1 功能描述

提供双向的 JavaScript 交互,包括:

  • Java 调用 JavaScript 代码

  • JavaScript 调用 Java 方法

  • 支持复杂数据类型的传递

  • 支持异步调用

2.6.2 内置 JavaScript 接口
/** * JavaScript 接口类,用于与 JavaScript 交互 */ public class WebViewJavaScriptInterface { /** * 设置视频播放速度 * <p> * 此方法由 JavaScript 调用,用于设置视频的播放速度 * <p> * @param speed 播放速度(0.5 - 2.0) * - 0.5: 半速播放 * - 1.0: 正常速度 * - 2.0: 两倍速播放 */ @JavascriptInterface public void setPlaybackSpeed(double speed) { // 实现代码 } /** * 获取当前播放速度 * <p> * 此方法由 JavaScript 调用,用于获取当前的播放速度 * <p> * @return 当前播放速度(默认 1.0) */ @JavascriptInterface public double getPlaybackSpeed() { return currentPlaybackSpeed; } /** * 通知 Java 层视频进入全屏 * <p> * 此方法由 JavaScript 调用,用于通知 Java 层视频进入全屏 * <p> * @param videoWidth 视频宽度 * @param videoHeight 视频高度 */ @JavascriptInterface public void onVideoEnterFullscreen(int videoWidth, int videoHeight) { // 实现代码 } /** * 通知 Java 层视频退出全屏 * <p> * 此方法由 JavaScript 调用,用于通知 Java 层视频退出全屏 */ @JavascriptInterface public void onVideoExitFullscreen() { // 实现代码 } }
2.6.3 使用示例
// 启用 JavaScript webView.setEnableJavaScript(true); // Java 调用 JavaScript webView.evaluateJavascript("document.getElementById('myElement').value", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { Log.d(TAG, "JavaScript 返回值: " + value); } }); // JavaScript 调用 Java // 在 HTML 中: // <script> // Android.setPlaybackSpeed(1.5); // var speed = Android.getPlaybackSpeed(); // </script>

三、API 接口文档

3.1 构造方法

3.1.1 基本构造方法
/** * 构造方法 * <p> * 创建一个新的 MyWebViewNew 实例 * <p> * @param context 上下文对象 */ public MyWebViewNew(Context context) { super(context); init(); } /** * 构造方法 * <p> * 创建一个新的 MyWebViewNew 实例 * <p> * @param context 上下文对象 * @param attrs 属性集合 */ public MyWebViewNew(Context context, AttributeSet attrs) { super(context, attrs); init(); } /** * 构造方法 * <p> * 创建一个新的 MyWebViewNew 实例 * <p> * @param context 上下文对象 * @param attrs 属性集合 * @param defStyleAttr 默认样式属性 */ public MyWebViewNew(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }

3.2 配置方法

3.2.1 初始化方法
/** * 初始化 WebView * <p> * 此方法会: * 1. 应用所有配置 * 2. 设置默认的 WebViewClient、WebChromeClient、DownloadListener * 3. 启用 JavaScript * 4. 启用缓存 * 5. 启用 Cookie * 6. 注入 JavaScript 接口 * <p> * 注意: * - 此方法必须在设置所有配置后调用 * - 如果需要修改配置,调用 reapplyConfig() 方法 */ public void init()
3.2.2 重新应用配置
/** * 重新应用配置 * <p> * 此方法会重新应用所有配置,用于在运行时修改配置后生效 * <p> * 注意: * - 此方法会重新创建 WebSettings、WebViewClient、WebChromeClient、DownloadListener * - 此方法不会重新加载当前页面 */ public void reapplyConfig()
3.2.3 JavaScript 配置
/** * 设置是否启用 JavaScript * <p> * 控制是否启用 WebView 的 JavaScript 功能 * <p> * @param enableJavaScript 是否启用 JavaScript */ public void setEnableJavaScript(boolean enableJavaScript) /** * 设置是否启用 JavaScript 自动弹窗 * <p> * 控制是否启用 WebView 的 JavaScript 自动弹窗功能 * <p> * @param enableJavaScriptCanOpenWindowsAutomatically 是否启用 JavaScript 自动弹窗 */ public void setEnableJavaScriptCanOpenWindowsAutomatically(boolean enable)
3.2.4 缩放配置
/** * 设置是否启用缩放 * <p> * 控制是否启用 WebView 的缩放功能 * <p> * @param enableZoom 是否启用缩放 */ public void setEnableZoom(boolean enableZoom) /** * 设置是否显示缩放控件 * <p> * 控制是否显示 WebView 的缩放控件(如放大/缩小按钮) * <p> * @param displayZoomControls 是否显示缩放控件 */ public void setDisplayZoomControls(boolean displayZoomControls)
3.2.5 缓存配置
/** * 设置缓存模式 * <p> * 控制 WebView 的缓存策略 * <p> * @param cacheMode 缓存模式 * - WebSettings.LOAD_DEFAULT: 默认模式 * - WebSettings.LOAD_CACHE_ELSE_NETWORK: 优先使用缓存 * - WebSettings.LOAD_NO_CACHE: 不使用缓存 * - WebSettings.LOAD_CACHE_ONLY: 只使用缓存 */ public void setCacheMode(int cacheMode) /** * 设置是否启用缓存 * <p> * 控制是否启用 WebView 的缓存功能 * <p> * @param enableCache 是否启用缓存 */ public void setEnableCache(boolean enableCache) /** * 设置缓存大小(字节) * <p> * 控制 WebView 的最大缓存大小 * <p> * @param cacheSize 缓存大小(字节),默认 8MB */ public void setCacheSize(int cacheSize)
3.2.6 Cookie 配置
/** * 设置是否启用 Cookie * <p> * 控制是否启用 WebView 的 Cookie 功能 * <p> * @param enableCookies 是否启用 Cookie */ public void setEnableCookies(boolean enableCookies)
3.2.7 其他配置
/** * 设置是否启用数据库存储 API * <p> * 控制是否启用 WebView 的数据库存储 API * <p> * @param enableDatabase 是否启用数据库存储 API */ public void setEnableDatabase(boolean enableDatabase) /** * 设置是否启用 DOM 存储 API * <p> * 控制是否启用 WebView 的 DOM 存储 API * <p> * @param enableDomStorage 是否启用 DOM 存储 API */ public void setEnableDomStorage(boolean enableDomStorage) /** * 设置是否启用应用缓存 * <p> * 控制是否启用 WebView 的应用缓存功能 * <p> * @param enableAppCache 是否启用应用缓存 */ public void setEnableAppCache(boolean enableAppCache) /** * 设置是否启用加载图片 * <p> * 控制是否启用 WebView 的图片加载功能 * <p> * @param enableLoadsImagesAutomatically 是否启用加载图片 */ public void setEnableLoadsImagesAutomatically(boolean enable) /** * 设置是否启用保存表单数据 * <p> * 控制是否启用 WebView 的表单数据保存功能 * <p> * @param enableSaveFormData 是否启用保存表单数据 */ public void setEnableSaveFormData(boolean enable) /** * 设置是否启用视口适配 * <p> * 控制是否启用 WebView 的视口适配功能 * <p> * @param enableUseWideViewPort 是否启用视口适配 */ public void setEnableUseWideViewPort(boolean enable) /** * 设置是否启用内容自适应 * <p> * 控制是否启用 WebView 的内容自适应功能 * <p> * @param enableLoadWithOverviewMode 是否启用内容自适应 */ public void setEnableLoadWithOverviewMode(boolean enable)

3.3 自定义组件方法

3.3.1 WebViewClient
/** * 设置自定义的 WebViewClient * <p> * 允许自定义 WebViewClient,用于处理页面加载事件 * <p> * 注意: * - 如果设置了自定义 WebViewClient,默认的 WebViewClient 将被替换 * - 自定义 WebViewClient 可以处理页面开始加载、结束加载、错误等事件 * <p> * @param customWebViewClient 自定义的 WebViewClient */ public void setCustomWebViewClient(WebViewClient customWebViewClient) /** * 获取当前的 WebViewClient * <p> * 返回当前使用的 WebViewClient * <p> * @return 当前的 WebViewClient */ public WebViewClient getCustomWebViewClient()
3.3.2 WebChromeClient
/** * 设置自定义的 WebChromeClient * <p> * 允许自定义 WebChromeClient,用于处理 JavaScript 对话框、进度条、全屏等事件 * <p> * 注意: * - 如果设置了自定义 WebChromeClient,默认的 WebChromeClient 将被替换 * - 自定义 WebChromeClient 会被自动包装,以保留全屏功能 * - 即使设置了自定义 WebChromeClient,全屏播放仍然可以正常工作 * <p> * @param customWebChromeClient 自定义的 WebChromeClient */ public void setCustomWebChromeClient(WebChromeClient customWebChromeClient) /** * 获取当前的 WebChromeClient * <p> * 返回当前使用的 WebChromeClient * <p> * @return 当前的 WebChromeClient */ public WebChromeClient getCustomWebChromeClient()
3.3.3 DownloadListener
/** * 设置自定义的 DownloadListener * <p> * 允许自定义 DownloadListener,用于处理文件下载事件 * <p> * 注意: * - 如果设置了自定义 DownloadListener,默认的下载逻辑将被替换 * - 自定义 DownloadListener 可以处理下载开始、进度、完成等事件 * <p> * @param customDownloadListener 自定义的 DownloadListener */ public void setCustomDownloadListener(DownloadListener customDownloadListener) /** * 获取当前的 DownloadListener * <p> * 返回当前使用的 DownloadListener * <p> * @return 当前的 DownloadListener */ public DownloadListener getCustomDownloadListener()

3.4 导航方法

3.4.1 基本导航
/** * 加载指定的 URL * <p> * 此方法会加载指定的 URL,并在加载完成后注入 JavaScript 接口 * <p> * @param url 要加载的 URL(必须以 http:// 或 https:// 开头) */ @Override public void loadUrl(String url) /** * 前进到下一页 * <p> * 如果可以前进,则前进到下一页 * <p> * @return 是否成功前进 */ public boolean goForward() /** * 后退到上一页 * <p> * 如果可以后退,则后退到上一页 * <p> * @return 是否成功后退 */ public boolean goBack() /** * 刷新当前页面 * <p> * 重新加载当前页面的内容 */ public void reload() /** * 停止加载当前页面 * <p> * 取消正在进行的页面加载 */ public void stopLoading()
3.4.2 导航状态
/** * 检查是否可以前进 * <p> * @return 是否可以前进 */ public boolean canGoForward() /** * 检查是否可以后退 * <p> * @return 是否可以后退 */ public boolean canGoBack() /** * 获取当前加载的 URL * <p> * @return 当前加载的 URL */ public String getCurrentUrl() /** * 获取当前页面的标题 * <p> * @return 当前页面的标题 */ public String getTitle()

3.5 播放速度控制

/** * 设置视频播放速度 * <p> * 控制视频的播放速度 * <p> * @param speed 播放速度(0.5 - 2.0) * - 0.5: 半速播放 * - 1.0: 正常速度 * - 2.0: 两倍速播放 */ public void setPlaybackSpeed(double speed) /** * 获取当前播放速度 * <p> * 返回当前的播放速度 * <p> * @return 当前播放速度(默认 1.0) */ public double getPlaybackSpeed()

3.6 监听器设置

3.6.1 下载监听器
/** * 设置下载监听器 * <p> * 允许自定义下载监听器,用于处理文件下载事件 * <p> * 注意: * - 如果设置了自定义下载监听器,默认的下载逻辑将被替换 * - 自定义下载监听器可以处理下载开始、进度、完成等事件 * <p> * @param listener 下载监听器 */ public void setOnDownloadListener(OnDownloadListener listener)
3.6.2 全屏监听器
/** * 设置全屏监听器 * <p> * 允许监听全屏进入和退出事件 * <p> * @param listener 全屏监听器 */ public void setOnFullscreenListener(OnFullscreenListener listener)
3.6.3 页面监听器
/** * 设置页面监听器 * <p> * 允许监听页面加载事件 * <p> * @param listener 页面监听器 */ public void setOnPageListener(OnPageListener listener)
3.6.4 播放速度监听器
/** * 设置播放速度变化监听器 * <p> * 允许监听播放速度变化事件 * <p> * @param listener 播放速度变化监听器 */ public void setOnPlaybackSpeedChangeListener(OnPlaybackSpeedChangeListener listener)

3.7 生命周期方法

/** * 处理 Activity 的 onResume 事件 * <p> * 恢复 WebView 的加载和播放 */ public void onResume() /** * 处理 Activity 的 onPause 事件 * <p> * 暂停 WebView 的加载和播放 */ public void onPause() /** * 处理 Activity 的 onDestroy 事件 * <p> * 销毁 WebView,释放资源 * <p> * 注意: * - 此方法必须在 Activity 的 onDestroy 中调用 * - 此方法会释放所有资源,避免内存泄漏 */ public void onDestroy()

3.8 其他方法

/** * 获取 WebSettings * <p> * 返回 WebView 的 WebSettings 对象,用于进一步配置 * <p> * @return WebSettings 对象 */ public WebSettings getSettings() /** * 清除缓存 * <p> * 清除 WebView 的所有缓存 */ public void clearCache() /** * 清除历史记录 * <p> * 清除 WebView 的所有历史记录 */ public void clearHistory() /** * 清除所有 Cookie * <p> * 清除 WebView 中存储的所有 Cookie */ public void clearCookies() /** * 清除表单数据 * <p> * 清除 WebView 中存储的所有表单

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1206950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

‌实战分享:AI在Web应用测试中的高效方案‌

测试行业的智能化拐点 2025年全球测试自动化渗透率突破65%&#xff08;Gartner&#xff09;&#xff0c;但传统脚本维护成本仍占据测试总时长40%。本文基于金融、电商领域实战案例&#xff0c;解析如何通过AI技术实现测试效率的指数级提升。 一、AI重构测试核心环节 1.1 智能…

AI驱动、0代码,设计并构建属于你的多平台原生 APP?

想必做移动端的朋友们肯定或多或少听说过 Kotlin 和 Compose Multiplatform, 前者是 JetBrains 开源、Google 首推用于 Android 开发(自2019 年 Google I/O 大会起)的现代开发语言, 后者是使用 Compose API 开发多端(Android、iOS、桌面端、Web端等)应用的UI框架。 但是…

‌软件开发前沿:生成式AI的实战挑战——给软件测试从业者的深度实战指南

一、生成式AI正在重塑测试工作流&#xff1a;从“手工编写”到“智能协同”‌ 生成式AI已不再是测试领域的实验性工具&#xff0c;而是成为‌日常质量保障流水线的核心引擎‌。根据2025年行业调研&#xff0c;‌75%的软件企业已将生成式AI纳入测试流程‌&#xff0c;其渗透率远…

ARM Q 饱和运算快速入门指南

在 ARM 嵌入式开发(尤其是信号处理、音视频编解码、传感器数据处理)中,普通算术运算的 “数值回绕” 问题极易导致数据错误,而**Q 饱和运算**是解决该问题的核心方案。在 ARM 嵌入式开发(尤其是信号处理、音视频编…

‌测试从业者调研:AI工具痛点与解决方案‌

AI测试工具的崛起与挑战 随着人工智能技术深入软件测试领域&#xff0c;AI工具如生成式对抗网络&#xff08;GAN&#xff09;、强化学习&#xff08;RL&#xff09;和自然语言处理&#xff08;NLP&#xff09;正重塑测试流程&#xff0c;提升效率与覆盖率。然而&#xff0c;测…

深入浅出 Julia:从零基础到科学机器学习

1. 引言&#xff1a;打破“双语言问题”的科学计算新范式 在很长一段时间里&#xff0c;科学计算和高性能工程领域被一种被称为“双语言问题”&#xff08;Two-Language Problem&#xff09;的现象所困扰。科学家和工程师们通常使用 Python 或 MATLAB 这样的高级动态语言进行算…

SCIR框架:基于自校正迭代精炼的增强型信息提取范式

1. 论文核心概要 (Executive Summary) 本论文提出了一种名为SCIR&#xff08;Self-Correcting Iterative Refinement&#xff09;的全新信息提取范式&#xff0c;旨在解决传统大语言模型微调范式中存在的高训练成本及偏好对齐困难等核心痛点&#xff0c;通过引入“即插即用”的…

为什么你的大模型微调项目像个“无底洞”?

—— 揭秘 LLM 落地中的高昂成本与“版本陷阱”在 AI 浪潮下&#xff0c;很多企业和开发者都有一个共识&#xff1a;“想让大模型在我的垂直领域&#xff08;如医疗、金融、法律&#xff09;表现好&#xff0c;必须进行微调&#xff08;Fine-tuning&#xff09;。”这听起来很美…

揭秘大模型微调中的【偏好对齐】陷阱

在 AI 落地应用中&#xff0c;我们经常遇到一种令人抓狂的现象&#xff1a; 你花大价钱微调了一个行业大模型&#xff0c;让它处理信息提取&#xff08;Information Extraction, IE&#xff09;任务&#xff0c;比如从合同中提取条款或从病历中提取诊断结果。 然而&#xff0c;…

详解无线网络的“防撞”智慧

无线网络&#xff08;Wi-Fi&#xff09;和蓝牙是我们每天都在用的技术&#xff0c;但你有没有想过&#xff1a;当几十台手机同时在一个房间里抢网速时&#xff0c;为什么信号没有在空气中撞成一锅粥&#xff1f; 答案在于一套精心设计的“交通规则”。今天我们结合6张核心技术…

数据仓库生命周期管理:从建模到退役全流程

数据仓库生命周期管理&#xff1a;从建模到退役全流程 关键词&#xff1a;数据仓库、生命周期管理、维度建模、ETL、数据退役、数据归档、数据质量监控 摘要&#xff1a;数据仓库就像企业的“数字大脑”&#xff0c;存储着海量业务数据&#xff0c;支撑着决策分析。但你知道吗&…

学习进度 7

今天接着琢磨昨天的过拟合和参数选择问题。先查了资料,知道过拟合就是模型把训练数据学太死,记了很多没用的细节,导致测试数据不准。然后跟着教程加了个Dropout层,就是训练的时候随机让一部分神经元不工作,防止模…

LVS的DR模式部署

目录 一、部署前提 二、所有节点基础配置 1.关闭防火墙和 SELinux 2.安装 ipvsadm 工具&#xff08;LVS 管理工具&#xff09; 三、 Director 节点配置 1.配置 VIP 2.配置 LVS 规则 3.开启 IP 转发&#xff08;可选&#xff09; 四、 Real Server 节点配置&#xff08…

MySQL 内置函数入门:基于 JAVA 基础的学习思考

作为一名刚接触 MySQL 仅 10 天的零基础新手&#xff0c;最初面对一堆陌生的内置函数时&#xff0c;总觉得记不住、用不好。但好在有一点 JAVA 基础&#xff0c;试着把 MySQL 函数和熟悉的 JAVA 方法做类比后&#xff0c;突然发现原本抽象的函数语法&#xff0c;一下子变得好理…

51c视觉~OCR~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft143/14456574 一、xxx .... 二、xxx .... 三、LightOnOCR OCR迎来“闪电时刻”&#xff1a;LightOnOCR-2以1B模型击败9B竞品&#xff0c;开源即达SOTA&#xff01; 最近&#xff0c;Light…

26年寒假生活指导1.23

以下是根据今日工作内容整理的学习日志: 📅 今日学习日志 - 日结单审批系统全栈开发与优化 日期:2026-01-23 项目:日结单管理系统 (RjdDailyWork)1. 🎯 核心目标 完成“日结单审批”功能的端到端开发,解决页面…

综合长文档效率战|万字毕业论文,用“快降重”统一风格、抢救AI率

摘要 毕业论文终稿往往是多部分拼合而成&#xff0c;风格不一&#xff0c;AI率参差不齐。最后一篇实测&#xff0c;我将一篇混合了引言、方法、分析、结论的万字长文档整体处理&#xff0c;测试“快降重”在大体量、混合内容下的综合表现与效率。 真实情况说明 我的论文不同章节…

视频推理帧率优化实战

&#x1f493; 博客主页&#xff1a;借口的CSDN主页 ⏩ 文章专栏&#xff1a;《热点资讯》 视频推理帧率优化实战&#xff1a;从瓶颈突破到智能节能 目录 视频推理帧率优化实战&#xff1a;从瓶颈突破到智能节能 引言&#xff1a;视频推理的帧率困境 一、问题与挑战&#xff1a…

基于微信小程序的儿童预防接种预约系统【源码+文档+调试】

&#x1f525;&#x1f525;作者&#xff1a; 米罗老师 &#x1f525;&#x1f525;个人简介&#xff1a;混迹java圈十余年&#xff0c;精通Java、小程序、数据库等。 &#x1f525;&#x1f525;各类成品Java毕设 。javaweb&#xff0c;ssm&#xff0c;springboot等项目&#…