APP接入腾讯X5内核(TBS)

前言

由于手机系统版本较低,对于某些网页系统webview无法加载,所以引入X5内核

TBS

腾讯TBS(Tencent Browser Service)是腾讯推出的一款移动端浏览器内核,也称为"TBS Core"或"TBS X5"。TBS是腾讯浏览服务的核心部分,用于提供Android设备上的浏览器功能。
腾讯TBS的主要特点和功能:

  • 高性能:TBS旨在提供更快、更稳定和更高效的网页浏览体验。它通过优化页面渲染性能,实现更快的网页加载速度和更流畅的用户体验。

  • 基于Chromium:TBS基于Google Chrome的开源项目Chromium,并根据Android系统的特点进行优化。这使得TBS能够更好地支持现代Web标准,并提供更广泛的网页兼容性。

  • 资源优化:TBS致力于减少资源消耗,包括内存和电池的使用,以便在移动设备上提供更好的性能和电池寿命。

  • 安全性:腾讯在TBS中加入了安全性增强功能,用于防范恶意网站和网络攻击,提供更可靠的浏览安全。

  • 支持扩展:TBS支持扩展和插件,允许开发人员根据需要添加自定义功能和特性。

在线集成

  1. 官网下载内核sdk https://x5.tencent.com/,放到项目中libs下,右键Add as Library
  2. 在Application添加初始化代码,打开APP后台下载
public class DemoApplication extends Application {
    private static final String TAG = "DemoApplication";

    @Override
    public void onCreate() {
        super.onCreate();
        /* [new] 独立Web进程演示 */
        if (!startX5WebProcessPreinitService()) {
            return;
        }

        /* 设置允许移动网络下进行内核下载。默认不下载,会导致部分一直用移动网络的用户无法使用x5内核 */
        QbSdk.setDownloadWithoutWifi(true);

        QbSdk.setCoreMinVersion(QbSdk.CORE_VER_ENABLE_202112);
        /* SDK内核初始化周期回调,包括 下载、安装、加载 */

        QbSdk.setTbsListener(new TbsListener() {

            /**
             * @param stateCode 用户可处理错误码请参考{@link com.tencent.smtt.sdk.TbsCommonCode}
             */
            @Override
            public void onDownloadFinish(int stateCode) {
                Log.i(TAG, "onDownloadFinished: " + stateCode);
            }

            /**
             * @param stateCode 用户可处理错误码请参考{@link com.tencent.smtt.sdk.TbsCommonCode}
             */
            @Override
            public void onInstallFinish(int stateCode) {
                Log.i(TAG, "onInstallFinished: " + stateCode);
            }

            /**
             * 首次安装应用,会触发内核下载,此时会有内核下载的进度回调。
             * @param progress 0 - 100
             */
            @Override
            public void onDownloadProgress(int progress) {
                Log.i(TAG, "Core Downloading: " + progress);
            }
        });

        /* 此过程包括X5内核的下载、预初始化,接入方不需要接管处理x5的初始化流程,希望无感接入 */
        QbSdk.initX5Environment(this, new PreInitCallback() {
            @Override
            public void onCoreInitFinished() {
                // 内核初始化完成,可能为系统内核,也可能为系统内核
            }

            /**
             * 预初始化结束
             * 由于X5内核体积较大,需要依赖wifi网络下发,所以当内核不存在的时候,默认会回调false,此时将会使用系统内核代替
             * 内核下发请求发起有24小时间隔,卸载重装、调整系统时间24小时后都可重置
             * 调试阶段建议通过 WebView 访问 debugtbs.qq.com -> 安装线上内核 解决
             * @param isX5 是否使用X5内核
             */
            @Override
            public void onViewInitFinished(boolean isX5) {
                Log.i(TAG, "onViewInitFinished: " + isX5);
                // hint: you can use QbSdk.getX5CoreLoadHelp(context) anytime to get help.
            }
        });
    }

    /**
     * 启动X5 独立Web进程的预加载服务。优点:
     * 1、后台启动,用户无感进程切换
     * 2、启动进程服务后,有X5内核时,X5预加载内核
     * 3、Web进程Crash时,不会使得整个应用进程crash掉
     * 4、隔离主进程的内存,降低网页导致的App OOM概率。
     *
     * 缺点:
     * 进程的创建占用手机整体的内存,demo 约为 150 MB
     */
    private boolean startX5WebProcessPreinitService() {
        String currentProcessName = QbSdk.getCurrentProcessName(this);
        // 设置多进程数据目录隔离,不设置的话系统内核多个进程使用WebView会crash,X5下可能ANR
        WebView.setDataDirectorySuffix(QbSdk.getCurrentProcessName(this));
        Log.i(TAG, currentProcessName);
        if (currentProcessName.equals(this.getPackageName())) {
            this.startService(new Intent(this, com.tencent.tbs.demo.utils.X5ProcessInitService.class));
            return true;
        }
        return false;
    }

}
  1. 在加载网页的Activity中使用 com.tencent.smtt.sdk.WebView 创建 WebView,相关配置与系统Webview类似

  2. 长按页面弹出菜单功能

    • X5WebView中弹出菜单不是通过startActionMode()实现的,首先实现IX5WebViewClientExtension,在onShowLongClickPopupMenu()中屏蔽弹出的系统菜单,实现ISelectionInterface,在updateHelperWidget()中弹出自定义acitonmode,相关代码如下
    if(webView.getX5WebViewExtension()!=null){
        webView.getX5WebViewExtension().setWebViewClientExtension(new MyWebViewExtension(webView));
        webView.getX5WebViewExtension().setSelectListener(webView.ISelectionInterfaceX);
    }
    
    public class MyWebViewExtension extends ProxyWebViewClientExtension {
        private WebView webView;
    
        public MyWebViewExtension(WebView webView) {
            this.webView = webView;
        }
    
        @Override
        public boolean onShowLongClickPopupMenu() {
            webView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (webView.getX5WebViewExtension() != null) {
                        webView.getX5WebViewExtension().enterSelectionMode(false);
                    }
                }
            }, 30);
    
            return true;
        }
    }
    
    class ISelectionInterfaceX implements ISelectionInterface{
    
            @Override
            public void onSelectionChange(Rect rect, Rect rect1, int i, int i1, short i2) {
    
            }
    
            @Override
            public void onSelectionBegin(Rect rect, Rect rect1, int i, int i1, short i2) {
    
            }
    
            @Override
            public void onSelectionBeginFailed(int i, int i1) {
    
            }
    
            @Override
            public void onSelectionDone(Rect rect, boolean b) {
    
            }
    
            @Override
            public void hideSelectionView() {
                if (mActionView != null) {
                    removeViewInLayout(mActionView);
                    mActionView = null;
                }
                if (mActionMode != null) {
                    mActionMode.finish();
                    mActionMode = null;
                }
            }
    
            @Override
            public void onSelectCancel() {
    
            }
    
            @Override
            public void updateHelperWidget(Rect rect, Rect rect1) {
                showContextMenu();
                post(new Runnable() {
                    @Override
                    public void run() {
                    	//自定义actionmode在mActionModeCallback中实现
                        mActionMode = startActionMode(mActionModeCallback, ActionMode.TYPE_FLOATING);
                    }
                });
            }
    
            @Override
            public void setText(String s, boolean b) {
    
            }
    
            @Override
            public String getText() {
                return null;
            }
    
            @Override
            public void onRetrieveFingerSearchContextResponse(String s, String s1, int i) {
    
            }
        }
    
    • X5内核下载不成功时,底层会默认使用系统内核,这个时候长按页面会执行 startActionModeForChild()(与直接使用系统的WebView不同的是会执行startActionMode())
    public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback, int type) {
            ActionMode actionMode = super.startActionModeForChild(originalView,mActionModeCallback, ActionMode.TYPE_FLOATING);
            return actionMode;
        }
    

离线集成

由于设备及网络原因,在线下载X5内核有失败的几率,所以可以使用离线集成,缺点是会增加安装包的体积

  1. 下载sdk添加到项目中(同在线集成第一步)

  2. 下载x5内核

    • 使用x5WebView打开腾讯TBS的调试页面debugtbs.qq.com,点击安装线上内核,在AndroidStudio Logcat中可以看到下载地址,每个设备Build.CPU_ABI 不一样,下载的内核也是不一样的
    • 下载内核后需要修改后缀名为apk,放到项目中assets目录下
    • 拷贝内核到设备中
    • 利用sdk进行内核安装
     public void startInstallX5(){
            if ("armeabi-v7a".equals(Build.CPU_ABI)) {
                boolean isExitCore = copyX5Core();
                if (isExitCore) {
                    // 存在内核文件
                    startInstallX5LocationCore();
                }else{
                    startLoadX5Core();
                }
            } else {
                startLoadX5Core();
            }
        }
    	/**
         * 将内核文件拷贝到指定目录
         */
        private boolean copyX5Core(){
            if(mContext.getExternalCacheDir()==null){
                return false;
            }
            String absolutePath = mContext.getExternalCacheDir().getAbsolutePath();
            String path = absolutePath+"/tbs";
            File dir = new File(path);
            if (!dir.exists()) {
               dir.mkdirs();
            }
            filePath = path+"/"+CORE_NAME;
            File file = new File(filePath);
            // 开始复制文件到指定目录
            try {
                if (!file.exists()) {
                    InputStream ins = mContext.getResources().getAssets().open("tbs/" + CORE_NAME);
                    Log.d(TAG, "开始读取内核文件");
                    OutputStream out = new FileOutputStream(file);
                    Log.d(TAG, "开始拷贝内核文件");
                    byte[] buf = new byte[1024];
                    int len;
    
                    while ((len = ins.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
                    ins.close();
                    out.close();
                    Log.d(TAG, "拷贝内核文件完成");
                }
    
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
    
            return true;
        }
     	/**
         * 开始安装本地离线内核
         */
        private void startInstallX5LocationCore() {
            try {
                QbSdk.installLocalTbsCore(mContext, CORE_VERSION, filePath);
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        QbSdk.initX5Environment(mContext, new QbSdk.PreInitCallback() {
                            @Override
                            public void onCoreInitFinished() {
                                Log.d(TAG, "onCoreInitFinished");
                            }
    
                            @Override
                            public void onViewInitFinished(boolean b) {
                                Log.d(TAG, "onViewInitFinished_p0=$p0");
                                int version = QbSdk.getTbsVersion(mContext);
                                if (version > 0) {
                                    timer.cancel();
                                }
                            }
                        });
                    }
                }, 0, 1000);
            }catch (Exception e){
    
            }
        }
    
    
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
腾讯X5内核WebView是一款基于Chromium内核的浏览器内核,相比于原生WebView,具有更好的性能和稳定性。以下是一些优化实践总结: 1. 集成腾讯X5内核 在使用WebView时,可以使用腾讯提供的X5内核替代原生内核。在集成X5内核时,需要在build.gradle文件中添加依赖: ``` dependencies { implementation 'com.tencent.tbs.tbssdk:sdk:43697' } ``` 2. 预加载 使用X5内核时,可以通过预加载提高WebView的响应速度。可以在应用启动时预加载X5内核: ``` // 在Application的onCreate方法中 QbSdk.initX5Environment(context, null) ``` 3. 启用多进程 如果应用中使用了多个WebView,可以启用多进程来提高性能和稳定性。可以在AndroidManifest.xml文件中设置: ``` <application android:name=".MyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:process=":webview"> ``` 4. 启用硬件加速 在使用X5内核时,可以启用硬件加速来提高渲染速度。可以在布局文件中设置: ``` <com.tencent.smtt.sdk.WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" android:layerType="hardware" /> ``` 5. 使用缓存 使用缓存可以减少网络请求,提高WebView的加载速度。可以在初始化WebView时设置: ``` val webSettings = webView.settings webSettings.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK ``` 以上是一些常见的优化实践总结,可以根据具体的场景进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值