「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」
导入腾讯的X5WebView
为什么不用系统的webview
X5内核相对于系统webview,具有下述明显优势:
- 速度快:相比系统webview的网页打开速度有30+%的提升;
- 省流量:使用云端优化腾讯体育技术使流量节省20+%;
- 更安全:安全问题可以在24小时内HTTPS修复;
- 更稳定:经过亿级用户的使用考验,CRASH率低于0.15%;
- 兼容好:无系统内核的碎片化问题,更少的兼容性问题;
- 体验优:支持夜安全间模式、适屏排版、字体设置等浏览增强功能;
- 功能全:在Html5、ES6上有更完整支持;安全教育平台登录入口
- 更强https域名大:集成强大安全教育的视频播放器,支持视频格式远多于系统webview;
- 视频和文件格式的支持x5内核多于系统内核
- 防劫持是x5内安全中心核的一大亮点
关于TBS
腾讯浏览服务是致力于优化移动端webview体验的整套解决方案。该方案由SDK、手机QQ浏览器X5内核和X5云端服务组成,解决移动端webview使用过程中出http 302现的一切问题,优化用户的浏览体验。同时HTTPS,腾讯还将持续提供后腾讯成长守护平台续的更新和优化,为开发者提供最新最优秀的功能和服务。
导kotlin语言入X5Webview腾讯先游
导入依赖
api 'com.tencent.tbs:tbssdk:44153'
implementation和api的区别
implementationhttp代理 类似于“praivte”,module引用implementhttps协议ation只应用于自身kotlin和java,不会传递。
api类似于“public”,其他module如果dependency该module,也可以引用到该module中的资源,会传递。
添加权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
>
<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" />
<application
...
<service
android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
android:label="dexopt"
android:process=":dexopt" >
</service>
</application>
</manifest>
具体安全教育平台登录入口可看 x5快速接HTTPS入 (tencent.com)
使用方法
fragment_web.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.tencent.smtt.sdk.WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
新建https域名一个类WebFragment
用argument传链接参数
companion object {
private const val LOAD_URL = "load_url"
fun load(url: String): WebFragment {
return WebFragment().apply {
arguments = bundleOf(LOAD_URL to url)
}
}
}
接收参数,并表用loadUrl
加载
arguments?.let { args ->
args.getString(LOAD_URL)?.let {
mBinding.webView.loadUrl(it)
}
}
配置WebSettkotlin和javaings
val webSettings: WebSettings = mBinding.webView.settings
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) { //解决网页中图片显示不出问题
webSettings.mixedContentMode = WebSettings.LOAD_DEFAULT
}
webSettings.javaScriptEnabled = true //支持JS
webSettings.domStorageEnabled = true //支持DOM Storage
webSettings.defaultTextEncodingName = "utf-8" //设置编码格式
webSettings.pluginState = WebSettings.PluginState.ON// 支持插件
webSettings.loadsImagesAutomatically = true //支持自动加载图片
webSettings.setSupportZoom(true) //支持缩放,默认为true。是下面那个的前提。
webSettings.builtInZoomControls = true //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.displayZoomControls = false //隐藏原生的缩放控件
webSettings.databaseEnabled = true // 数据库存储API是否可用
webSettings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN //WebView底层布局算法
webSettings.cacheMode =
WebSettings.LOAD_CACHE_ELSE_NETWORK //设置缓存,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。本地没有缓存时才从网络上获取
webSettings.allowFileAccess = true //设置可以访问文件
webSettings.javaScriptCanOpenWindowsAutomatically = true //支持通过JS打开新窗口
//设置自适应屏幕,两者合用
webSettings.useWideViewPort = true //将图片调整到适合WebView的大小
webSettings.loadWithOverviewMode = true // 缩放至屏幕的大小
接着在首页HomeFragment
输入搜索链接转跳到WebFragment
fragment_home.xml
搜索框+FrameLayout
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<EditText
android:id="@+id/ed_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="166dp"
android:layout_marginEnd="16dp"
android:padding="12dp"
android:imeOptions="actionSearch"
android:background="@drawable/gray_rounded_shape"
android:drawableLeft="@drawable/ic_search_gray_24dp"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
软键盘右下方的搜索按钮
android:imeOptions="actionSearch"
HomeFragment
监听搜索按钮
mBinding.edSearch.setOnEditorActionListener(OnEditorActionListener { textView, actionId, keyEvent ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//点击搜索要做的操作
toWebView()
return@OnEditorActionListener true
}
false
})
用childFragmentManager来管理WebFragment后面还涉及多窗口
```kotlin
fun toWebView(){
childFragmentManager.commit {
addToBackStack("HomeFragment")
var search = "${mBinding.edSearch.text}"
val baiduUrl = "https://www.baidu.com/s?wd=$search"
var webFragment = WebFragment.load(baiduUrl)
add(R.id.content, webFragment)//不能使用replace,否则每次返回都要重建
}
}
监听返回键返回桌面
requireActivity().onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
isEnabled = childFragmentManager.backStackEntryCount > 0
if (isEnabled){
childFragmentManager.popBackStackImmediate()
}
else requireActivity().finish()
}
})