腾讯TBS X5浏览器内核入坑指南
接入X5内核而不是原生的WebView的主要原因是X5内核兼容性好(待考证)。其实博主以为原生WebView会奔溃的原因是某些用户在第三方应用市场胡乱“升级”WebView导致不兼容所致。
我司的这个产品只是使用WebView通过JS与客户端交互,并没有使用其他的诸如视频等等功能。但就算如此,在某些机型上仍然会崩溃,但是情况有所好转。
1 接入过程¶
接入过程很简单,下面简单的记录下接入的流程。博主现在接入的是Android SDK(3.3完整版)。
1.1 下载SDK以及DEMO¶
此步骤我们需要拿到两个东西:一个jar文件、一个so文件。
根据所需情况下载SDK、SDK接入示例-Android Studio。
SDK里面我们需要用到的是tbs_sdk_thirdapp_v*.jar 这个包。
这个包我们需要放到app/libs文件夹中。
然后DEMO里面我们需要提取一个so库文件,位置在X5WebDemo/src/main/jniLibs/armeabi/liblbs.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
}
}
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中配置如下:
但是TBS X5只提供了armeabi
这个so,直接按照官方的配置是加载X5不成功的,可以参考:https://x5.tencent.com/tbs/technical.html#/detail/sdk/1/34cf1488-7dc2-41ca-a77f-0014112bcab7
按照官方说法,我们只能这么配置:
这样的话,其他第三方lib也要使用armeabi
里面的so。
幸好,其他lib有armeabi-v7a
这个架构的so文件,我们copy了一份放到了armeabi
下面,然后使用上面的ndk配置,可以正常运行。
2.2 Cookie同步问题¶
调整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,产生了冲突,删掉一个就好了。