在使用Webview 加载一个网页时,网页上的视频无法播放,想播放视频,只需要引入 TBS X5 内核即可,关于引入不多介绍,我前面的文章也有介绍接入,百度好多都写的很好。

当接入了X5 内核,我们使用com.tencent.smtt.sdk.WebView替换默认的WebView,用法几乎一样,但是这是腾讯微信和QQ 使用的浏览器内核,其中优化的很不错,很多原生的坑,也解决了。

Webview 的初始化

我使用的是 X5WebView 是自定义的继承自com.tencent.smtt.sdk.WebView,没有做什么操作,可以直接使用com.tencent.smtt.sdk.WebView

private void init() {

        mWebView = new X5WebView(this, null);

        mViewParent.addView(mWebView, new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.FILL_PARENT,
                FrameLayout.LayoutParams.FILL_PARENT));
        WebSettings webSetting = mWebView.getSettings();
        webSetting.setAllowFileAccess(true);
        webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
        webSetting.setSupportZoom(true);
        webSetting.setBuiltInZoomControls(true);
        webSetting.setUseWideViewPort(true);
        webSetting.setSupportMultipleWindows(false);//这里一定得是false,不然打开的网页中,不能在点击打开了
        // webSetting.setLoadWithOverviewMode(true);
        webSetting.setAppCacheEnabled(true);
        // webSetting.setDatabaseEnabled(true);
        webSetting.setDomStorageEnabled(true);
        webSetting.setJavaScriptEnabled(true);
        webSetting.setGeolocationEnabled(true);
        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
        webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());
        webSetting.setDatabasePath(this.getDir("databases", 0).getPath());
        webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0)
                .getPath());
        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
        // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
        // webSetting.setPreFectch(true);
        long time = System.currentTimeMillis();
        mWebView.loadUrl(mIntentUrl.toString());
        CookieSyncManager.createInstance(this);
        CookieSyncManager.getInstance().sync();


        //这一段,尤其重要。对应的参数也都有介绍。可以修改。
        if (mWebView.getX5WebViewExtension() != null) {
            //开启X5全屏播放模式
            Bundle data = new Bundle();

            data.putBoolean("standardFullScreen", false);// true表示标准全屏,false表示X5全屏;不设置默认false,

            data.putBoolean("supportLiteWnd", true);// false:关闭小窗;true:开启小窗;不设置默认true,

            data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1

            mWebView.getX5WebViewExtension().invokeMiscMethod("setVideoParams",
                    data);
        }
    }

BrowserActivity

public class BrowserActivity extends CommonLoginActivity {
    /**
     * 作为一个浏览器的示例展示出来,采用android+web的模式
     */
    private X5WebView mWebView;
    private ViewGroup mViewParent;
    private ProgressBar mPageLoadingProgressBar = null;
    private String mIntentUrl;

    private boolean isFirstJoin = true;


    @Override
    public int addRootLayout() {

        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        Intent intent = getIntent();
        if (intent != null) {
            try {
//              mIntentUrl = new URL(intent.getData().toString());
                mIntentUrl = intent.getStringExtra("url");
            } catch (NullPointerException e) {

            } catch (Exception e) {
            }
        }
        //
        try {
            if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 11) {
                getWindow()
                        .setFlags(
                                android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                                android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            }
        } catch (Exception e) {
        }

        /*
         * getWindow().addFlags(
         * android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);
         */
        return R.layout.activity_web;
    }

    @Override
    public void initChildViews() {
        mViewParent = (ViewGroup) findViewById(R.id.acty_web_layout_content);
        mPageLoadingProgressBar = (ProgressBar) findViewById(R.id.web_pb);// new
        init();
    }


    @Override
    public void initData() {

    }

    @Override
    protected void initListener() {
        //获取渲染的的进度
        WebViewClient webViewClient = new WebViewClient() {
            @Override
            public void onPageFinished(com.tencent.smtt.sdk.WebView webView, String s) {
                //获取网页的标题
                if (isFirstJoin) {
                    String title = webView.getTitle();
                    commonTitleLayout.setTitleText(title);
                    isFirstJoin = !isFirstJoin;
                }

            }
        };

        WebChromeClient webChromeClient = new WebChromeClient() {
            @Override
            public void onProgressChanged(com.tencent.smtt.sdk.WebView webView, int newProgress) {
                if (newProgress == 100) {
                    mPageLoadingProgressBar.setVisibility(View.INVISIBLE);
                } else {
                    mPageLoadingProgressBar.setProgress(newProgress);
                }
            }
        };

//        mWebView.setWebChromeClient(webChromeClient);

        mWebView.setWebViewClient(webViewClient);
    }


    private void init() {

        mWebView = new X5WebView(this, null);

        mViewParent.addView(mWebView, new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.FILL_PARENT,
                FrameLayout.LayoutParams.FILL_PARENT));
        WebSettings webSetting = mWebView.getSettings();
        webSetting.setAllowFileAccess(true);
        webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
        webSetting.setSupportZoom(true);
        webSetting.setBuiltInZoomControls(true);
        webSetting.setUseWideViewPort(true);
        webSetting.setSupportMultipleWindows(false);//
        // webSetting.setLoadWithOverviewMode(true);
        webSetting.setAppCacheEnabled(true);
        // webSetting.setDatabaseEnabled(true);
        webSetting.setDomStorageEnabled(true);
        webSetting.setJavaScriptEnabled(true);
        webSetting.setGeolocationEnabled(true);
        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
        webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());
        webSetting.setDatabasePath(this.getDir("databases", 0).getPath());
        webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0)
                .getPath());
        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
        // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
        // webSetting.setPreFectch(true);
        long time = System.currentTimeMillis();
        mWebView.loadUrl(mIntentUrl.toString());
        CookieSyncManager.createInstance(this);
        CookieSyncManager.getInstance().sync();


        //这一段,尤其重要。
        if (mWebView.getX5WebViewExtension() != null) {
            //开启X5全屏播放模式
            Bundle data = new Bundle();

            data.putBoolean("standardFullScreen", false);// true表示标准全屏,false表示X5全屏;不设置默认false,

            data.putBoolean("supportLiteWnd", true);// false:关闭小窗;true:开启小窗;不设置默认true,

            data.putInt("DefaultVideoScreen", 2);// 1:以页面内开始播放,2:以全屏开始播放;不设置默认:1

            mWebView.getX5WebViewExtension().invokeMiscMethod("setVideoParams",
                    data);
        }
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mWebView != null && mWebView.canGoBack()) {
                mWebView.goBack();
                if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 16)
//                  changGoForwardButton(mWebView);
                    return true;
            } else
                return super.onKeyDown(keyCode, event);
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {

        if (mWebView != null)
           clearWebview();
        super.onDestroy();
    }
 /**
     * 解决WebView内存泄露的问题
     */
    public  void  clearWebview(){
        if( mWebView!=null) {

            // 如果先调用destroy()方法,则会命中if (isDestroyed()) return;这一行代码,需要先onDetachedFromWindow(),再
            // destory()
            ViewParent parent = mWebView.getParent();
            if (parent != null) {
                ((ViewGroup) parent).removeView(mWebView);
            }

            mWebView.stopLoading();
            // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
            mWebView.getSettings().setJavaScriptEnabled(false);
            mWebView.clearHistory();
            mWebView.clearView();
            mWebView.removeAllViews();
            mWebView.destroy();

        }
    }

    public static void actionStart(Context context, String url) {
        Intent intent = new Intent(context, BrowserActivity.class);
        intent.putExtra("url", url);
        context.startActivity(intent);
    }


}

特别注意的是这里

WebChromeClient webChromeClient = new WebChromeClient() {
            @Override
            public void onProgressChanged(com.tencent.smtt.sdk.WebView webView, int newProgress) {
                if (newProgress == 100) {
                    mPageLoadingProgressBar.setVisibility(View.INVISIBLE);
                } else {
                    mPageLoadingProgressBar.setProgress(newProgress);
                }
            }
        };

//        mWebView.setWebChromeClient(webChromeClient);

当我添加上时,发现播放视频后,返回,会多出一个界面,很丑,这里我还没有解决,这里添加主要是想设置progress 参数,当然也可以做个假的,在那里动。

1.点击图中的视频,进入(图-2)

android VideoView 没有全屏 webview播放视频不能全屏_android


2.点击返回键,进入(图-3)

android VideoView 没有全屏 webview播放视频不能全屏_全屏_02

3.出现如下这样的一个界面,

android VideoView 没有全屏 webview播放视频不能全屏_全屏_03

测试后mWebView.setWebChromeClient(webChromeClient);不设置就不会有(图-3)出现,原因暂时还没有查到。

activity_web.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">



    <ProgressBar
        android:id="@+id/web_pb"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="@dimen/y6" />


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <FrameLayout
            android:id="@+id/acty_web_layout_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </FrameLayout>
    </RelativeLayout>

</LinearLayout>

通过上面这些也就基本实现了,我们加载网页播放网页中的,视频,和你将这个网页放到qq、微信上打开的效果一样

补充一条,就是app module 的build.gradle中defaultConfig中,n d k,中需要设置,abiFilters "armeabi", "x86","mips",测试的时候 vivo xplay6 的cpu是 arm64-v8a,因此出现编译打包后,无法调用X5内核。这里要注意。

android {
    aaptOptions {
        cruncherEnabled = false
        useNewCruncher = false
    }
    //在android 标签下,唯一的属性就是compileSdkVersion,buildToolsVersion
    compileSdkVersion rootProject.ext.android["compileSdkVersion"]
    buildToolsVersion rootProject.ext.android["buildToolsVersion"]
    defaultConfig {
        applicationId rootProject.ext.android["applicationId"]
        minSdkVersion rootProject.ext.android["minSdkVersion"]
        targetSdkVersion rootProject.ext.android["targetSdkVersion"]
        versionCode rootProject.ext.android["versionCode"]
        versionName rootProject.ext.android["versionName"]
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true

        ndk {
//            abiFilters "arm64-v8a","armeabi", "armeabi-v7a", "x86", "x86_64","mips","mips64"
//            abiFilters "armeabi",  "x86", "x86_64","mips","mips64"
//            abiFilters "armeabi", "x86"
            abiFilters "armeabi", "x86","mips"


//            vivo xplay6 的ndk是 arm64-v8a
        }
    }

}