跳转至

腾讯TBS X5浏览器内核入坑指南

接入X5内核而不是原生的WebView的主要原因是X5内核兼容性好(待考证)。其实博主以为原生WebView会奔溃的原因是某些用户在第三方应用市场胡乱“升级”WebView导致不兼容所致。

我司的这个产品只是使用WebView通过JS与客户端交互,并没有使用其他的诸如视频等等功能。但就算如此,在某些机型上仍然会崩溃,但是情况有所好转。

1 接入过程

接入过程很简单,下面简单的记录下接入的流程。博主现在接入的是Android SDK(3.3完整版)。

1.1 下载SDK以及DEMO

SDK以及DEMO下载链接

此步骤我们需要拿到两个东西:一个jar文件、一个so文件。

根据所需情况下载SDK、SDK接入示例-Android Studio。

SDK里面我们需要用到的是tbs_sdk_thirdapp_v*.jar 这个包。
这个包我们需要放到app/libs文件夹中。
jar包放置位置

然后DEMO里面我们需要提取一个so库文件,位置在X5WebDemo/src/main/jniLibs/armeabi/liblbs.so,提取后放到我们自己项目的对应位置。
so库放置位置

1.2 开始接入SDK

SDK的接入文档在:https://x5.tencent.com/tbs/guide/sdkInit.html

SDK的接入可以查看官方文档,这里简单的记录一下接入过程

1.在自己的Application类中预初始化X5内核

初始化操作可以通过QbSdk.initX5Environment方法来完成,如下。

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ......
        QbSdk.initX5Environment(this, new QbSdk.PreInitCallback() {
            @Override
            public void onCoreInitFinished() {
                // X5内核加载完成后回调
                LogUtils.i("onCoreInitFinished -----------");
            }

            @Override
            public void onViewInitFinished(boolean b) {
                // 传入参数b为true表示加载X5成功,false表示加载失败
                LogUtils.i("onViewInitFinished " + b + " -----------");
            }
        }); // pre-init X5
    }
}
这个函数内是异步执行所以不会阻塞App主线程,这个函数内是轻量级执行所以对App启动性能没有影响,当App后续创建WebView时就可以首次加载X5内核了

2.AndroidManifest.xml里加入权限声明

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

3.将原本webkit相关的类全部替换成X5内核中的

这个步骤包括xml代码以及Java代码里面的。具体的替换表如下:

系统内核 SDK内核
android.webkit.ConsoleMessage com.tencent.smtt.export.external.interfaces.ConsoleMessage
android.webkit.CacheManager com.tencent.smtt.sdk.CacheManager(deprecated)
android.webkit.CookieManager com.tencent.smtt.sdk.CookieManager
android.webkit.CookieSyncManager com.tencent.smtt.sdk.CookieSyncManager
android.webkit.CustomViewCallback com.tencent.smtt.export.external.interfaces.IX5WebChromeClient.CustomViewCallback
android.webkit.DownloadListener com.tencent.smtt.sdk.DownloadListener
android.webkit.GeolocationPermissions com.tencent.smtt.export.external.interfaces.GeolocationPermissionsCallback
android.webkit.HttpAuthHandler com.tencent.smtt.export.external.interfaces.HttpAuthHandler
android.webkit.JsPromptResult com.tencent.smtt.export.external.interfaces.JsPromptResult
android.webkit.JsResult com.tencent.smtt.export.external.interfaces.JsResult
android.webkit.SslErrorHandler com.tencent.smtt.export.external.interfaces.SslErrorHandler
android.webkit.ValueCallback com.tencent.smtt.sdk.ValueCallback
android.webkit.WebBackForwardList com.tencent.smtt.sdk.WebBackForwardList
android.webkit.WebChromeClient com.tencent.smtt.sdk.WebChromeClient
android.webkit.WebHistoryItem com.tencent.smtt.sdk.WebHistoryItem
android.webkit.WebIconDatabase com.tencent.smtt.sdk.WebIconDatabase
android.webkit.WebResourceResponse com.tencent.smtt.export.external.interfaces.WebResourceResponse
android.webkit.WebSettings com.tencent.smtt.sdk.WebSettings
android.webkit.WebSettings.LayoutAlgorithm com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm
android.webkit.WebStorage com.tencent.smtt.sdk.WebStorage
android.webkit.WebView com.tencent.smtt.sdk.WebView
android.webkit.WebViewClient com.tencent.smtt.sdk.WebViewClient

为了确保替换的完整,可以使用脚本checkqbsdk.sh进行扫描,windows上使用TBSSdk接入扫描工具.exe进行扫描。脚本放在所有源码的顶级目录下运行即可。后续的版本发布前尽量都运行一遍扫描,以免上次扫描后新提交的代码有未替换的情况发生。
替换不完全时,可能发生的问题是关于cookie的身份错误、类转换时的crash等。cookie问题产生的原理是:一段代码把cookie塞给了系统内核,另外一段代码尝试从x5的内核里读取cookie就失败了。类转换的错误产生的原理是:比如xml里指定的是系统的webview,java的代码里把它当作x5的webview使用。

至此,X5内核的WebView已经可以跑起来了。下面还有一些踩过的坑。

2 踩坑指南

2.1 加载X5内核不成功的问题

因为我司产品中接入了其他第三方so,这些so文件没有提供了armeabi这个so,只提供了下面这三个。所以集成X5内核之前,app的gradle中配置如下:

ndk {
    abiFilters 'armeabi-v7a', 'armeabi-v8a', 'arm64-v8a'
}

但是TBS X5只提供了armeabi这个so,直接按照官方的配置是加载X5不成功的,可以参考:https://x5.tencent.com/tbs/technical.html#/detail/sdk/1/34cf1488-7dc2-41ca-a77f-0014112bcab7

按照官方说法,我们只能这么配置:

ndk {
    abiFilters 'armeabi'
}

这样的话,其他第三方lib也要使用armeabi里面的so。

幸好,其他lib有armeabi-v7a这个架构的so文件,我们copy了一份放到了armeabi下面,然后使用上面的ndk配置,可以正常运行。

调整cookie的使用:
com.tencent.smtt.sdk.CookieManager和com.tencent.smtt.sdk.CookieSyncManager的相关接口的调用,在接入SDK后,需要放到创建X5的WebView之后(也就是X5内核加载完成)进行;否则,cookie的相关操作只能影响系统内核。

在这个产品中所有的业务操作(WebView在这部分使用)都需要登录,登录是一个native界面。登录成功后需要保存Cookie。但是X5必须在WebView创建也就是new之后才能使用X5里面的Cookie。所以这部分的Cookie不能通过CookieManager了,只能使用其他方式来保存Cookie,然后在WebView创建的时候通过CookieSyncManager来同步Cookie。

2.3 屏蔽长按事件

https://x5.tencent.com/guide?id=2013

tbs1.x:使用webview.getView().setLongClickListener()设置X5webview的长按监听,在listener中重写onLongClick方法,返回true就能禁止掉X5 webview的长按功能。

tbs2.x:在IX5WebViewClientExtension的实现类的onShowLongClickPopupMenu方法中直接return true;

2.4 集成三方SDK报错

集成数据魔盒SDK时遇到编译报错:

AGPBI: {"kind":"error","text":"Program type already present: com.tencent.smtt.export.external.DexLoader$TbsCorePrivateClassLoader","sources":[{}],"tool":"D8"}

因为数据魔盒SDK内置了腾讯X5,而项目中也集成了X5,产生了冲突,删掉一个就好了。

评论