集成TBS
自带的webview使用起来很多网页不兼容,有很多坑,这里推荐使用TBS,也就是X5内核。
https://x5.tencent.com/tbs/sdk.html
接入文档:
https://x5.tencent.com/docs/access.html
SDK接入
jar包方式集成 您可将官网下载的jar包复制到您的App的libs目录,并且通过Add As Library的方式集成TBS SDK
Gradle方式集成 您可以在使用SDK的模块的dependencies中添加引用进行集成:
1 | api 'com.tencent.tbs:tbssdk:44286' |
kts
1 | api("com.tencent.tbs:tbssdk:44286") |
使用到的网址 如果设备有防火墙 需要把下面的地址加入白名单,否则无法下载X5内核。
soft.imtt.qq.com
wss.tim.qq.com
log.tbs.qq.com
cfg.imtt.qq.com
tbs.imtt.qq.com
cdntips.net
tcdnos.com
TBS下载失败
TBS是分发的,也就是你调用下载,也不一定下载,这就导致内核安装变得让人难以捉摸。
这里建议下载成功的时候,不要重启找到下载的内核复制出来,千万不要重启,重启自动安装就会把下载的删除。
下载目录
假如我的APP的包名是com.xhkjedu.xh_control_browser
下载成功后会在下面的目录中产生一个x5.tbs
文件
1 | /data/data/com.xhkjedu.xh_control_browser/app_tbs_64/core_private |
本地安装
1 | val canLoadX5 = QbSdk.canLoadX5(context) |
引用的
1 | api("com.tencent.tbs:tbssdk:44286") |
实际下载的是46281
版本的x5.tbs
百度网盘下载x5.tbs
链接:https://pan.baidu.com/s/1Ly-ZQxv2nLtFG4txDic0Wg
提取码:psvm
混淆配置
为了保障X5功能的正常使用,您需要在您的proguard-rules.pro
文件中添加如下配置:
1 | -dontwarn dalvik.** |
添加权限和服务
在您的AndroidManifest.xml增加如下权限:
1 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
在AndroidManifest.xml中增加内核首次加载时优化Service声明。
该Service仅在TBS内核首次Dex加载时触发并执行dex2oat任务,任务完成后自动结束。
1 | <service |
安装TBS内核
官方下载
Application的onCreate中进行初始化
1 | import android.content.Context |
注意
不要在onViewInitFinished中自己调用下载,会和本身的下载冲突,导致下载失败。
1 | override fun onViewInitFinished(isX5: Boolean) { |
使用本地文件
src/main
下添加assets
文件夹
文件夹中放入x5.tbs
文件
1 | import android.content.Context |
其中复制的目标位置是
1 | /sdcard/Android/data/com.xhkjedu.xh_control_browser/files/app/x5.tbs |
使用自己的下载地址
默认使用官方下载,失败再使用自己的镜像。
1 | import android.app.AlarmManager |
重启APP
安装内核后重启才生效
1 | fun reStartApp(context: Context){ |
方式2
1 | fun reStartApp2(){ |
退出到主Launcher
我们应用的Activity都退出后,应用本身不一定退出,这是Android本身方便下次快速启动导致的。
但是TBS有时必须重启应用才能生效,但是直接退出应用,在管控平板上没有退出到上一个应用中,所以这里退出到主Launcher,再结束本应用。
1 | override fun onBackPressed() { |
测试是否生效
在没有自定义UA的情况下,使用您的app打开网页
1 | http://soft.imtt.qq.com/browser/tes/feedback.html |
显示000000
表示加载的是系统内核,显示大于零的数字表示加载了x5内核(该数字是x5内核版本号)
替换
包名替换
将源码和XML里的系统包和类替换为SDK里的包和类,具体对应如下:
系统内核 | 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 |
XML替换
布局xml里的声明也需要替换,例如:
1 | <com.tencent.smtt.sdk.WebView |
调用
1 |
|
JS注入
src/main
下添加assets
文件夹
添加m_inject.js文件
1 | var dom = document.getElementById("menu-btn"); |
工具类
1 | import android.content.Context; |
调用
1 | val jsstr = AndroidFileUtil.getFromAssets(this, "m_inject.js") |
我们可以在下面的回调中调用注入方法
1 | mWebView.setWebChromeClient(object : WebChromeClient() { |
返回上一页
1 | override fun onBackPressed() { |
申请权限
1 | private val REQUEST_EXTERNAL_STORAGE = 1 |