android框架 - 腾讯TBSX5WebView - 替代系统WebView

腾讯TBSX5WebView - 替代系统自带WebView

官网: https://x5.tencent.com/docs/index.html

介绍:

腾讯浏览服务(TBS,Tencent Browsing Service)整合腾讯底层浏览技术和腾讯平台资源及能力,提供整体浏览服务解决方案。腾讯浏览服务面向应用开发商和广大开发者,提供浏览增强,内容框架,广告体系,H5游戏分发,大数据等服务,能够帮助应用开发商大幅改善应用体验,有效提升开发,运营,商业化的效率。

优点

传统系统内核(Webview)存在适配成本高、不安全、不稳定、耗流量、速度慢、视频播放差、文件能力差等问题,这是移动应用开发商在进行Hybrid App开发时普遍面临的难题。腾讯浏览服务基于腾讯X5内核解决方案(包括内核和云服务),能够有效解决传统移动web技术面临的普遍问题,同时能极大扩展应用(Hybrid App)内浏览场景的服务能力。

使用步骤

  1. 添加依赖 或者 官网下载jar包导入
  2. 一般自定义WebView控件再使用
  3. 在布局文件添加刚自定义好的控件
  4. 调用刚定义好的WebView

Demo - 带进度条的WebView

1、添加依赖 或者 官网下载jar包导入

添加依赖

//文件:app\build.gradle
implementation 'com.tencent.tbs.tbssdk:sdk:43697'

添加权限

//文件:app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!-- 硬件加速对X5视频播放非常重要,建议开启 -->
    <uses-permission android:name="android.permission.GET_TASKS" />

添加服务:该Service仅在TBS内核首次Dex加载时触发并执行dex2oat任务, 任务完成后自动结束

//文件:app/src/main/AndroidManifest.xml
<service
            android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
            android:label="dexopt"
            android:process=":dexopt" />

享受页面视频的完整播放体验,页面的Activity需要声明android:configChanges=“orientation|screenSize|keyboardHidden”
避免输入法界面弹出后遮挡输入光标的问题:android:windowSoftInputMode=“stateHidden|adjustResize”

//文件:app/src/main/AndroidManifest.xml
<activity
            android:name=".TBSX5WebView.BaseTencentWebActivity"
            android:configChanges="orientation|screenSize|keyboardHidden">
            android:windowSoftInputMode="stateHidden|adjustResize"
</activity>

在非硬绘手机和声明需要controller的网页上,视频切换全屏和全屏切换回页面内会出现视频窗口透明问题,需要如下设置

文件:\src\main\res\values\styles.xml
<item name="android:windowIsTranslucent">false</item>
2、一般自定义WebView控件再使用

文件:X5WebView.java

import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;
//注意WebView要继承com.tencent.smtt.sdk.WebView包下的
//并非android.webkit.WebView包
public class X5WebView extends WebView {
	//设置顶部加载进度条
    private ProgressBar mprogressBar;
	//给自定义类创建构造方法,一般Alt+insert -> constructor -> 全部构造
	// initWebView(context)为WebView作配置
    public X5WebView(Context context) {
        super(context);
        initWebView(context);
    }

    public X5WebView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initWebView(context);
    }

    public X5WebView(Context context, AttributeSet attributeSet, int i) {
        super(context, attributeSet, i);
        initWebView(context);
    }

    public X5WebView(Context context, AttributeSet attributeSet, int i, boolean b) {
        super(context, attributeSet, i, b);
        initWebView(context);
    }

    public X5WebView(Context context, AttributeSet attributeSet, int i, Map<String, Object> map, boolean b) {
        super(context, attributeSet, i, map, b);
        initWebView(context);
    }

	// initWebView(context)为WebView作配置
    private void initWebView(Context context) {
        //添加进度条
        mprogressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
        //LayoutParams实现xml布局动态设置,主要设置View的位置(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 10);
        mprogressBar.setLayoutParams(layoutParams);
        mprogressBar.setProgress(0);
        addView(mprogressBar);

        //设置Settings,可直接照搬
        WebSettings settings = this.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setAllowFileAccess(true);
        settings.setSupportZoom(true);
        settings.setBuiltInZoomControls(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        settings.setUseWideViewPort(true);
        settings.setSupportMultipleWindows(true);
        settings.setAppCacheEnabled(true);
        //此项影响网页的加载功能
        settings.setDomStorageEnabled(true);
        settings.setGeolocationEnabled(true);
        settings.setAppCacheMaxSize(Long.MAX_VALUE);
        settings.setPluginState(WebSettings.PluginState.ON_DEMAND);
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);

        //初始化WebViewClient
        setWebViewClient(new WebViewClient(){
            //页面内跳转,禁止调用浏览器打开新链接
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String s) {
                webView.loadUrl(s);
                return super.shouldOverrideUrlLoading(webView, s);
            }
        });

        //初始化WebChromeClient
        setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView webView, int i) {
                super.onProgressChanged(webView, i);
                if (i == 100) {
                    mprogressBar.setVisibility(GONE);
                } else {
                    if (mprogressBar.getVisibility() == GONE){
                        mprogressBar.setVisibility(VISIBLE);
                    }
                    mprogressBar.setProgress(i);
                }
            }
        });
    }
}

3、在布局文件添加刚自定义好的控件

文件:activity_base_tencen_web.xml
此处添加了一个ToolBar为后续添加返回主界面按键和用其他浏览器(非必须)
注意:提前学习ToolBar的使用
效果

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

	//ToolBar(非必须)
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
    </android.support.v7.widget.Toolbar>

    <com.hong.frampractice.TBSX5WebView.X5WebView
        android:id="@+id/myX5WebView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
4、调用刚定义好的WebView
public class BaseTencentWebActivity extends AppCompatActivity {

    X5WebView myX5WebView;
    String baseurl = "https://www.baidu.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base_tencen_web);
        
        //x5内核初始化接口
        initQbsdk();
        //如果用到布局文件的ToolBar才需要设置(非必须)
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setTitle("实现文档");
        
        myX5WebView = findViewById(R.id.myX5WebView);
        //清理缓存和历史(非必须)
        myX5WebView.clearCache(true);
        myX5WebView.clearHistory();
        //视频为了避免闪屏和透明问题,需要如下设置
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
		//启用硬件加速
        initHardwareAccelerate();
		//加载url
        myX5WebView.loadUrl(baseurl);

    }
	//x5内核初始化接口
    private void initQbsdk() {
        QbSdk.initX5Environment(this, new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(boolean arg0) {
                //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                Log.d("app", "腾讯X5内核初始化回调 onViewInitFinished is " + arg0);
            }
            @Override
            public void onCoreInitFinished() {
                Log.d("app", "腾讯X5内核初始化回调 onCoreInitFinished");
            }
        });
    }

    //启用硬件加速:由于硬件加速自身并非完美无缺,所以Android提供选项来打开或者关闭硬件加速,默认是关闭。可以在4个级别上打开或者关闭硬件加速
    private void initHardwareAccelerate() {
        try {
            if (Build.VERSION.SDK_INT >= 11) {
            	//Window级别硬件加速
                getWindow()
                        .setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            }
        } catch (Exception e) {
        }
    }

    //设置返回键监听
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (myX5WebView != null && myX5WebView.canGoBack()) {
                myX5WebView.goBack();
                return true;
            } else {
                return super.onKeyDown(keyCode, event);
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    //释放资源,防止内存泄露
    @Override
    protected void onDestroy() {
        if (myX5WebView != null) {
            myX5WebView.destroy();
        }
        super.onDestroy();
    }
	
	//设置ToolBar菜单选项
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_webview, menu);
        return true;
    }

    //Toolbar选择选项监听
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish();
                break;
            case R.id.share:
                Intent intent = new Intent();
                intent.setData(Uri.parse(baseurl));
                intent.setAction(Intent.ACTION_VIEW);
                startActivity(intent);
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }
}

效果

在这里插入图片描述

来自官方的提醒 官方接入文档

  1. x5暂时不提供64位so文件,为了保证64位手机能正常加载x5内核,请参照如下链接修改相关配置https://x5.tencent.com/tbs/technical.html#/detail/sdk/1/34cf1488-7dc2-41ca-a77f-0014112bcab7
  2. 调整cookie的使用:
    com.tencent.smtt.sdk.CookieManager和com.tencent.smtt.sdk.CookieSyncManager的相关接口的调用,在接入SDK后,需要放到创建X5的WebView之后(也就是X5内核加载完成)进行;否则,cookie的相关操作只能影响系统内核。
  3. 以下接口禁止(直接或反射)调用,避免视频画面无法显示:
    webview.setLayerType()
    webview.setDrawingCacheEnabled(true);
  4. app 自定义 UA 的说明
    如果 app 需要自定义 UA,建议采取在 SDK 默认UA 后追加 app UA 的方式示例:
    webSetting.setUserAgentString(webSetting.getUserAgentString() + APP_NAME_UA);
    其中 APP_NAME_UA 是 app 自定义 UA
  5. app混淆时的处理
    由于我们提供的 TBS jar 已经混淆过,所以 App 混淆时可以不再混淆我们的 TBS jar,或者也可以把我们的混淆策略 proguard 点击下载 加入 App 的混淆策略里注意:如果 App没有按照该规则混淆了 TBS jar,可能导致无法使用 x5内核
  6. Tbs视频播放器接入说明
    TBS不仅提供了强大的网页浏览功能,更提供了强大的页面H5视频播放支持,播放器同时支持页面,小窗,全屏播放体验,强大的解码能力,包括mp4,rmvb,flv,avi等26种视频格式支持。
    TBS播放器的播放场景不仅局限于H5页面播放,也可以接入一般的视频流链接,比如本地文件,网络的视频流链接。开发者如果想播放一个视频链接,在不自己开发播放器的前提下,一般做法是将视频的播放链接放到一个Intent里面,抛给系统的播放器进行播放,那么当你集成了TBS后,你只需要通过简单的方式接入视频播放调用接口,这样你不需要写任何一句关于播放器的代码,就可以享受一个本地播放器体验,播放视频再不需要Intent来跨App、跨进程的调用了。

下面是视频播放接入的步骤:
1.第一步
AndroidManifest需要如下的注册:

<activity
	android:name="com.tencent.smtt.sdk.VideoActivity"
	android:configChanges="orientation|screenSize|keyboardHidden"
	android:exported="false"
	android:launchMode="singleTask"
	android:alwaysRetainTaskState="true">
	<intent-filter>
		<action android:name="com.tencent.smtt.tbs.video.PLAY" />
		<category android:name="android.intent.category.DEFAULT" />
	</intent-filter>
</activity>

说明:VideoActivity是TBS自带的组件,需要App如上配置
2. 第二步
播放视频的调用接口
通过TbsVideo的静态方法,如下:

public static boolean canUseTbsPlayer(Context context)
//判断当前Tbs播放器是否已经可以使用。
public static void openVideo(Context context, String videoUrl)
//直接调用播放接口,传入视频流的url
public static void openVideo(Context context, String videoUrl, Bundle extraData)
//extraData对象是根据定制需要传入约定的信息,没有需要可以传如null
//extraData可以传入key: "screenMode", 值: 102, 来控制默认的播放UI
//类似: extraData.putInt("screenMode", 102); 来实现默认全屏+控制栏等UI
  1. 优化异常上报:
    为了提高合作方的webview场景稳定性,及时发现并解决x5相关问题,当客户端发生crash等异常情况并上报给服务器时请务必带上x5内核相关信息。x5内核异常信息获取接口为:com.tencent.smtt.sdk.WebView.getCrashExtraMessage(context)。以bugly日志上报为例:
  UserStrategy strategy = new UserStrategy(appContext);
  strategy.setCrashHandleCallback(new CrashReport.CrashHandleCallback() {
    public Map<String, String> onCrashHandleStart(int crashType, String errorType, String errorMessage, String errorStack) {
      LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
      String x5CrashInfo = com.tencent.smtt.sdk.WebView.getCrashExtraMessage(appContext);
      map.put("x5crashInfo", x5CrashInfo);
      return map;
    }
    @Override
    public byte[] onCrashHandleStart2GetExtraDatas(int crashType, String errorType, String errorMessage, String errorStack) {
      try {
        return "Extra data.".getBytes("UTF-8");
      } catch (Exception e) {
        return null;
      }
    }
  });
  CrashReport.initCrashReport(appContext, APPID, true, strategy);

猜你喜欢

转载自blog.csdn.net/weixin_44565784/article/details/100057603