在使用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)
2.点击返回键,进入(图-3)
3.出现如下这样的一个界面,
测试后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
}
}
}