Android 7.0 本身不再支持传统的 NPAPI 插件(如 Flash Player),这意味着,在 Android 7.0 及更高版本的 WebView(用于在 App 内显示网页的组件)或 Chrome 浏览器中,网页如果试图使用 <embed> 或 <object> 标签加载 Flash (.swf) 视频,是无法播放的。

当我们在 Android 7.0 的上下文中谈论“网页视频插件”时,通常有以下几种理解和实现方式:
利用现代 Web 标准(推荐)
这是最主流、最兼容的方案,现代网页视频主要依靠 HTML5 的 <video> 标签,它依赖于浏览器内置的解码器,对于 App 这意味着你需要使用 Android 的 WebView 组件来加载包含 HTML5 视频的网页。
关键技术点:
-
WebView 配置: 为了确保视频播放体验良好,你需要对
WebView进行一些关键配置。-
启用硬件加速:这是视频播放流畅的基础。
(图片来源网络,侵删)<!-- 在 AndroidManifest.xml 中对 Activity 启用 --> <activity android:name=".MyActivity" android:hardwareAccelerated="true" /> -
设置正确的 WebView 属性:
WebView webView = findViewById(R.id.webview); WebSettings settings = webView.getSettings(); // 启用 JavaScript (HTML5 视频通常需要) settings.setJavaScriptEnabled(true); // 启用 DOM Storage (很多网站需要) settings.setDomStorageEnabled(true); // 启用混合内容 (HTTP 网页中播放 HTTPS 视频) settings.setMixedContentMode(WebSettings.MIXED_CONTENT_MODE_COMPATIBLE); // 设置 User-Agent (有时为了兼容特定网站需要) // settings.setUserAgentString("MyApp User Agent"); // 设置插件状态 (虽然 NPAPI 已死,但这是标准配置) settings.setPluginState(WebSettings.PluginState.ON);
-
-
处理全屏播放: HTML5 视频播放时通常会请求全屏,在
WebView中,你需要重写onShowCustomView和onHideCustomView方法来处理这个逻辑,否则视频无法全屏显示。// 在你的 Activity 或 WebViewClient 中处理 private View mCustomView; private WebChromeClient.CustomViewCallback mCustomViewCallback; // ... 在 WebChromeClient 中 @Override public void onShowCustomView(View view, CustomViewCallback callback) { // 如果已经有自定义视图,先隐藏 if (mCustomView != null) { onHideCustomView(); return; } // 保存视图和回调 mCustomView = view; mCustomViewCallback = callback; // 将自定义视图添加到你的布局中 FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); addContentView(view, layoutParams); } @Override public void onHideCustomView() { if (mCustomView == null) { return; } // 隐藏视图 mCustomView.setVisibility(View.GONE); // 从布局中移除 ((ViewGroup) mCustomView.getParent()).removeView(mCustomView); mCustomView = null; // 通知回调 if (mCustomViewCallback != null) { mCustomViewCallback.onCustomViewHidden(); mCustomViewCallback = null; } }
优点:
- 兼容性最好:所有现代网站都使用此标准。
- 无需额外插件:依赖系统内核,维护简单。
- 性能好:利用硬件解码。
缺点:
- 依赖网页本身:如果网页的视频格式或编码不兼容,则无法播放。
- 全屏处理需要手动编码:增加了开发复杂度。
使用第三方视频播放库(WebView 增强方案)
有时,网页上的视频源可能使用了特殊的加密格式(如 HLS, DASH)或者你想要获得比系统 WebView 更好的播放控制体验,这时,你可以采用“拦截视频 URL 并用原生播放器打开”的方案。
工作原理:
- 创建一个自定义的
WebViewClient。 - 在
shouldOverrideUrlLoading方法中,检查 URL 是否是视频流(包含.m3u8、.mpd等后缀,或来自特定域名)。 - 如果是视频 URL,则阻止
WebView加载它,并启动一个原生的视频播放器(如 ExoPlayer)来播放这个 URL。 - 如果不是视频 URL,则正常交给
WebView处理。
关键技术点:
-
ExoPlayer: Google 官方推荐的视频播放库,功能强大,支持几乎所有主流格式(HLS, DASH, MP4, MKV 等),并且有强大的 DRM 支持。
(图片来源网络,侵删)// 在 shouldOverrideUrlLoading 中 @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { Uri url = request.getUrl(); String urlString = url.toString(); // 检查是否是视频链接 (这里只是简单示例,实际判断会更复杂) if (urlString.contains(".mp4") || urlString.contains(".m3u8")) { // 启动 ExoPlayer 播放视频 Intent intent = new Intent(this, VideoPlayerActivity.class); intent.putExtra("video_url", urlString); startActivity(intent); return true; // 表示已处理,不再由 WebView 加载 } return false; // 其他链接由 WebView 加载 } -
VideoPlayerActivity: 这个 Activity 负责使用 ExoPlayer 播放视频。
// VideoPlayerActivity.java public class VideoPlayerActivity extends AppCompatActivity { private SimpleExoPlayer player; private PlayerView playerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video_player); playerView = findViewById(R.id.player_view); String videoUrl = getIntent().getStringExtra("video_url"); // ... 初始化 ExoPlayer 并准备播放 } // ... 其他 ExoPlayer 生命周期管理代码 }
优点:
- 播放体验可控:可以自定义播放器 UI、控制逻辑。
- 格式支持广:ExoPlayer 可以播放 WebView 原生不支持或播放不佳的格式。
- 性能优异:ExoPlayer 同样利用硬件解码,性能稳定。
缺点:
- 开发复杂度高:需要维护 WebView 和原生播放器两套逻辑。
- 可能破坏网页体验:直接跳出 WebView 播放,用户可能无法使用网页内嵌的播放器控件(如弹幕、倍速等,除非你自己实现)。
使用混合框架(如 Cordova/PhoneGap)
如果你的 App 是使用 Cordova 或类似的混合框架开发的,插件”的概念就非常明确了。
工作原理:
Cordova 允许你使用 JavaScript 调用原生的 Java/Kotlin 代码,你可以创建一个自定义的 Cordova 插件,这个插件封装了原生的视频播放功能(比如调用 ExoPlayer)。
关键技术点:
-
创建插件: 你需要定义一个 JavaScript 接口(
window.plugins.MyVideoPlayer.play('url'))和一个对应的原生类(MyVideoPlayer.java)来处理这个调用。 -
原生实现: 原生类的实现与方案二中的
VideoPlayerActivity类似,最终还是会调用 ExoPlayer 或其他播放库。 -
网页调用: 在你的网页中,当需要播放视频时,不再使用
<video>标签,而是调用你定义的插件方法:// 网页 JS 代码 function playVideo() { var videoUrl = "http://example.com/video.mp4"; if (window.plugins && window.plugins.myVideoPlayer) { window.plugins.myVideoPlayer.play(videoUrl); } else { // 降级处理,或者提示用户 alert("Video player plugin not found."); } }
优点:
- 封装性好:对网页开发者透明,他们只需要调用 JS 接口。
- 体验统一:可以提供一个在 App 内一致的视频播放体验。
缺点:
- 依赖框架:必须基于 Cordova 等混合框架。
- 开发和维护成本:需要开发和维护 Cordova 插件本身。
总结与建议
| 方案 | 核心思想 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| HTML5 + WebView | 使用 Web 标准,让 WebView 原生支持。 |
简单、兼容性好、无需额外开发。 | 依赖网页,全屏处理需手动,格式受限。 | 大多数常规 App 内嵌网页视频需求。 |
| URL 拦截 + ExoPlayer | 拦截视频 URL,用原生播放器打开。 | 播放体验可控、格式支持广、性能好。 | 开发复杂,可能破坏网页体验。 | 对视频播放体验有高要求,或需播放特殊格式的场景。 |
| Cordova 插件 | 通过 JS 调用原生播放器。 | 封装性好,体验统一。 | 依赖混合框架,插件开发维护成本高。 | 基于 Cordova/PhoneGap 开发的 App。 |
给 Android 7.0 开发者的最终建议:
-
首选方案一:对于绝大多数情况,请首先尝试使用配置良好的
WebView来加载 HTML5 网页,这是最简单、最稳定、最符合趋势的做法,确保处理好全屏播放的逻辑。 -
在方案一无法满足时,考虑方案二:如果你发现网页的视频源(如 HLS 流)在
WebView中播放卡顿、无法播放,或者你希望提供更一致的播放体验,那么采用“URL 拦截 + ExoPlayer”的方案是最佳选择,ExoPlayer 是 Android 平台上事实上的标准视频播放解决方案。 -
避免寻找“万能插件”:不要再寻找一个像过去 Flash Player 那样的“一劳永逸”的视频插件,Android 7.0 及以后,视频播放的重心已经从“浏览器插件”转向了“系统级解码器”和“强大的原生播放库”。
-
注意权限:如果视频来自网络,确保你的 App 在
AndroidManifest.xml中有网络访问权限:<uses-permission android:name="android.permission.INTERNET" />
