Android WebView HTML5 Video Spawns MediaPlayer 永远存在于 Samsung S4 [找到黑客答案]

标签 android html video webview android-mediaplayer

据我所知,这似乎是最新的三星设备所特有的。 S4 将执行此操作。 Nexus 7 不会。

如果带有 WebChromeClient 的 WebView 开始播放 HTML5 视频,它会创建一个 MediaPlayer 实例。视频结束后,似乎没有办法通过 System.exit(0) 杀死 MediaPlayer。

这是我的整个 MainActivity.java

package com.test.webviewtest;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

public class MainActivity extends Activity {
    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        webView = new WebView(this);
        webView.setWebChromeClient(new WebChromeClient());
        String html = "<video width=\"320\" height=\"240\" controls autoplay>" +
                "<source src=\"http://www.w3schools.com/html/movie.mp4\" " +
                "type=\"video/mp4\"></video>";
        webView.loadData(html, "text/html", null);
        setContentView(webView);
    }

    @Override
    protected void onPause(){
        super.onPause();
        // attempt to kill the MediaPlayer here...
    }

}

当然这在 list 中是必需的

<uses-permission android:name="android.permission.INTERNET"/>

只要您点击视频,logcat 就会开始吐出 MediaPlayer 消息,而且它永远不会停止。播放视频时有一些有用的,但之后,它只是记录

02-25 17:13:19.395     220-8584/? V/MediaPlayerService﹕ [470] notify (0x51b7aa00, 3, 100, 0)
02-25 17:13:19.395    8532-8610/? V/MediaPlayer﹕ message received msg=3, ext1=100, ext2=0
02-25 17:13:19.395    8532-8610/? V/MediaPlayer﹕ buffering 100
02-25 17:13:19.395    8532-8610/? V/MediaPlayer﹕ callback application
02-25 17:13:19.405    8532-8610/? V/MediaPlayer﹕ back from callback
02-25 17:13:20.406     220-8584/? V/MediaPlayerService﹕ [470] notify (0x51b7aa00, 3, 100, 0)
02-25 17:13:20.406    8532-8544/? V/MediaPlayer﹕ message received msg=3, ext1=100, ext2=0
02-25 17:13:20.406    8532-8544/? V/MediaPlayer﹕ buffering 100
02-25 17:13:20.406    8532-8544/? V/MediaPlayer﹕ callback application
02-25 17:13:20.406    8532-8544/? V/MediaPlayer﹕ back from callback
02-25 17:13:21.407     220-8584/? V/MediaPlayerService﹕ [470] notify (0x51b7aa00, 3, 100, 0)
02-25 17:13:21.407    8532-8611/? V/MediaPlayer﹕ message received msg=3, ext1=100, ext2=0
02-25 17:13:21.407    8532-8611/? V/MediaPlayer﹕ buffering 100
02-25 17:13:21.407    8532-8611/? V/MediaPlayer﹕ callback application
02-25 17:13:21.417    8532-8611/? V/MediaPlayer﹕ back from callback

这种重复永远不会结束,直到您强行关闭或卸载或其他激烈的事情。 我已经试过了:

  • webView.onPause();这会暂停视频,使其停止在后台播放,但不会终止 MediaPlayer。
  • webView.destroy();仍然没有阻止那个僵尸 MediaPlayer
  • webView = null;
  • webView = new WebView(this);还是不行
  • finish();
  • 我也尝试过各种方法来获取 WebChromeClient 并销毁它,但没有任何效果。

我会在尝试更多内容时更新此列表。感谢您的帮助。

  • 我现在还尝试使用 webView.loadData("hi", "text/html", null); 将 webView 重定向到非视频内容还活着……

破解答案

嗯,这是我能找到的最好的。如果有人有更好的解决方案,请仍然告诉我。

为了得到MediaPlayer停止,我告诉它去页面 <video>指向视频以外的内容的标签。

String html = "<video width=\"320\" height=\"240\" controls>" +
    "<source src=\"http://www.w3schools.com/html/NOT_A_MOVIE.mp4\" " +
    "type=\"video/mp4\"></video>";
webView.loadData(html, "text/html", null); 

当我执行此操作时,我会在屏幕上看到一个视频播放器,当我单击播放按钮时,它会记录

02-26 12:26:37.112    220-11354/? V/MediaPlayerService﹕ [576] notify (0x47fa92b8, 100, 1, -1004)
02-26 12:26:37.112  11264-11325/com.test.webviewtest V/MediaPlayer﹕ message received msg=100, ext1=1, ext2=-1004
02-26 12:26:37.112  11264-11325/com.test.webviewtest E/MediaPlayer﹕ error (1, -1004)
02-26 12:26:37.112  11264-11325/com.test.webviewtest V/MediaPlayer﹕ callback application
02-26 12:26:37.112  11264-11325/com.test.webviewtest V/MediaPlayer﹕ back from callback
02-26 12:26:37.122  11264-11264/com.test.webviewtest E/MediaPlayer﹕ Error (1,-1004)

从现在开始,MediaPlayer似乎大部分都死了(只有一点点活着)。它会停止所有日志记录 Activity ,这是期望的结果。唯一留下的痕迹是当您强行关闭应用程序时,您仍然会看到它。

02-26 12:29:35.826      220-738/? V/MediaPlayerService﹕ Client(576) destructor pid = 11264
02-26 12:29:35.836      220-738/? V/MediaPlayerService﹕ disconnect(576) from pid 11264
02-26 12:29:35.836      220-738/? W/MediaPlayerService﹕ native_window_api_disconnect returned an error: Broken pipe (-32)

我同意,但真正的解决方案会更好。显然,我会将不良视频与自动播放连接起来,这样崩溃就可以在后台发生,但这就是框架。


更新 2-27-14 虽然这“修复”了三星设备上的问题,但它确实会破坏其他设备,因此这不是一个好的解决方案。在其他设备(已测试 Nexus 7)上,此代码将使 WebView 无法用于任何 future 的调用。当我找到更多信息时,我会更新它。如果您不需要在应用程序的剩余生命周期内呈现另一个 WebView,我想这没问题,但我需要它以便稍后能够加载另一个页面。

最佳答案

对我来说,除了以下之外,没有其他解决方案有效:

android.os.Process.killProcess(android.os.Process.myPid());

这带来了您实际上无法从内部创建 Activity 的麻烦,但我已经通过第二个过程克服了这个问题。

关于Android WebView HTML5 Video Spawns MediaPlayer 永远存在于 Samsung S4 [找到黑客答案],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22029891/

相关文章:

java - WebView 和 Nexus Chrome 浏览器的工作方式与我在 PC 上的 Chrome 浏览器不同

android - 为什么这一行 xmlns :android ="http://schemas.android.com/apk/res/android" must be the first in the layout xml file?

android - 删除自动建议及其布局

javascript - 加载 iFrame 并打印

html - 为什么我的 <table> 数据会溢出其父级的 <div> 引导容器?

video - 在 OpenCV 中创建 AVI 文件

android - ListView自定义第一个cell

html - 如何删除两个 span 标签之间的空白?

c++ - OpenCV VideoCapture 不能在 Visual Studio 之外工作

c# - MediaFoundation 找不到视频捕获仿真器驱动程序。但 DirectShow 确实