LZ-Says:想和你喝酒是假,想醉你懷裏是真。
前言
最近一段時間,都是在被前端虐了,還好,談不上遊刃有餘,至少可以實現所需功能,調試起來也不會太過於懵逼。
當然,和大佬相比,還是差距很多。前段時間,因爲個人原因,暫時停滯了前行之路,而今,慢慢拾起,希望努力實現自己想要的。
好久沒碰 Android,今天拿 TBS X5 作爲練手~
TBS X5 瞭解
曾經,在 Android 的世界裏,加載網頁,WebView 首當其衝,但是,當理想遇到顯示,又出現如下情況 (節選自 TBS X5 官方) :
- 傳統系統內核 ( Webview ) 存在適配成本高、不安全、不穩定、耗流量、速度慢、視頻播放差、文件能力差等問題
那麼針對以上提出的問題,我們該怎麼辦呢?
-
優化?Enmmm,Sorry,打擾了。
-
第三方開源方案,Enmmm,似乎還是有些問題,應用率以及使用率相對來說有待期待。
-
TBS X5?試試?
那麼 TBS X5 是個什麼鬼?它又是擁有着何樣的才能呢?一起來看~
騰訊瀏覽服務(TBS,Tencent Browsing Service)整合騰訊底層瀏覽技術和騰訊平臺資源及能力,提供整體瀏覽服務解決方案。
而 ta 又具有何方風采呢?爲了省事兒,直接官方盜圖~
-
速度快:相比系統 webview 的網頁打開速度有 30+% 的提升;
-
省流量:使用雲端優化技術使流量節省 20+%;
-
更安全:安全問題可以在 24 小時內修復;
-
更穩定:經過億級用戶的使用考驗,CRASH 率低於 0.15%;
-
兼容好:無系統內核的碎片化問題,更少的兼容性問題;
-
體驗優:支持夜間模式、適屏排版、字體設置等瀏覽增強功能;
-
功能全:在 Html5、ES6 上有更完整支持;
-
更強大:集成強大的視頻播放器,支持視頻格式遠多於系統 webview;
-
視頻和文件格式的支持 x5 內核多於系統內核;
-
防劫持是 x5 內核的一大亮點
簡單瞭解之後,我們開始準備玩轉操作~
TBS X5 實踐
TBS X5 SDK 下載地址:https://x5.tencent.com/tbs/sdk.html
針對官方提供 SDK,這裏我們選擇 Android SDK(完整版),最新的更新日期爲:2019-02-13。
首先創建項目,將下載下來的 So 庫文件以及 Jar 包倒入工程,如下所示:
設置支持的 CPU 架構以及開啓 DataBinding 支持:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
...
// 支持 CPU 架構
ndk {
abiFilters "armeabi"
}
...
}
...
dataBinding {
enabled = true
}
}
dependencies {
...
implementation files('libs/tbs_sdk_thirdapp_v4.3.0.1020_43633_sharewithdownload_withoutGame_obfs_20190111_105200.jar')
}
定義常量工具類:
package com.tbs.tbsdemo.app
/**
* @author: heliquan
* @data: 2019/3/28
* @desc: 生活不易 且行且珍惜
*/
/**
* 傳遞狀態標誌
*/
const val S_STATE_CODE = "stateCode"
/**
* 加載網頁
*/
const val S_LOAD_URL = "loadUrl"
/**
* 加載視頻
*/
const val S_LOAD_VIDEO = "loadVideo"
/**
* URL 地址
*/
const val U_URL = "https://heliquan.blog.csdn.net/"
/**
* 在線視頻地址
*/
const val U_VIDEO = "https://img-cdn-qiniu.dcloud.net.cn/uniapp/doc/uni-app20190127.mp4"
隨後嘛,添加對應的權限:
<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.GET_TASKS"/>
<!-- 硬件加速對X5視頻播放非常重要,建議開啓 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
定義 BaseApplication,初始化 TBS X5:
package com.tbs.tbsdemo.app.base
import android.app.Application
import android.util.Log
import com.tencent.smtt.sdk.QbSdk
/**
* @author: heliquan
* @data: 2019/3/28
* @desc:
*/
class BaseApplication : Application() {
override fun onCreate() {
super.onCreate()
initTencentX5()
}
private fun initTencentX5() {
val cb = object : QbSdk.PreInitCallback {
override fun onViewInitFinished(arg0: Boolean) {
Log.e("HLQ_Struggle", "x5 內核初始化完成的回調,爲true表示x5內核加載成功,否則表示x5內核加載失敗,會自動切換到系統內核:$arg0")
}
override fun onCoreInitFinished() {
Log.e("HLQ_Struggle", "x5 內核初始化 onCoreInitFinished")
}
}
QbSdk.initX5Environment(applicationContext, cb)
}
}
當然,不要忘記在 AndroidManifest 中指明,如下:
<application
android:name=".app.base.BaseApplication"
...
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning">
...
</application>
接下來,搭建一個類似下面的門戶:
並在首頁設置跳轉,這裏默認已經創建了 Web 加載頁:
package com.tbs.tbsdemo
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.View
import com.tbs.tbsdemo.app.S_LOAD_URL
import com.tbs.tbsdemo.app.S_LOAD_VIDEO
import com.tbs.tbsdemo.app.S_STATE_CODE
/**
* @author HLQ_Struggle
* @date 2019年3月24日
* @desc
*/
class MainActivity : AppCompatActivity() {
private val mSelfActivity = MainActivity@ this
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/**
* Activity 跳轉
* @param stateCode
*/
private fun startActivity(stateCode: String) {
var intent = Intent(mSelfActivity, X5WebActivity::class.java)
intent.putExtra(S_STATE_CODE, stateCode)
startActivity(intent)
}
fun loadUrl(view: View) {
startActivity(S_LOAD_URL)
}
fun loadVideo(view: View) {
startActivity(S_LOAD_VIDEO)
}
}
而最後則是開始着手編寫我們 Web 加載頁,簡單說下想法:
- Web 頁根據上頁傳遞標誌符進行動態設置加載 URL;
- Web 頁加載時,頂部需要有進度條;
- 剩下則是 Web 常規設置,例如 WebSettings 等。
哦可,首先着手編輯 Web 頁的佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".X5WebActivity">
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminateDrawable="@color/colorBar"
android:progress="0"
android:max="100"
android:layout_height="3dp"/>
<com.tencent.smtt.sdk.WebView
android:id="@+id/x5_web"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</layout>
下面,則是我們的 Web 加載頁,很 easy,直接附上源碼吧~
package com.tbs.tbsdemo
import android.databinding.DataBindingUtil
import android.graphics.Bitmap
import android.graphics.PixelFormat
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.KeyEvent
import android.view.View
import android.widget.Toast
import com.tbs.tbsdemo.app.*
import com.tbs.tbsdemo.databinding.ActivityX5WebBinding
import com.tencent.smtt.export.external.interfaces.SslError
import com.tencent.smtt.export.external.interfaces.SslErrorHandler
import com.tencent.smtt.sdk.WebChromeClient
import com.tencent.smtt.sdk.WebSettings
import com.tencent.smtt.sdk.WebView
import com.tencent.smtt.sdk.WebViewClient
/**
* @author HLQ_Struggle
* @date 2019年3月24日
* @desc 重新感受下 Android 之美 重新領略 Kotlin 優雅
* */
class X5WebActivity : AppCompatActivity() {
private val mSelfActivity = X5WebActivity@ this
var mDataBind: ActivityX5WebBinding? = null
var mLoadUrl = ""
override fun onCreate(savedInstanceState: Bundle?) {
window.setFormat(PixelFormat.TRANSLUCENT)
super.onCreate(savedInstanceState)
mDataBind = DataBindingUtil.setContentView(mSelfActivity, R.layout.activity_x5_web)
initLoadUrl()
initX5WebViewSettings()
}
private fun initLoadUrl() {
var stateCode = intent.getStringExtra(S_STATE_CODE)
when (stateCode) {
S_LOAD_URL -> {
mLoadUrl = U_URL
}
S_LOAD_VIDEO -> {
mLoadUrl = U_VIDEO
}
else -> {
Toast.makeText(mSelfActivity, "傳了個鳥啊這是???", Toast.LENGTH_SHORT).show()
}
}
}
private fun initX5WebViewSettings() {
// 支持獲取手勢焦點
mDataBind?.x5Web?.requestFocusFromTouch()
initWebSettings()
initChromeClient()
mDataBind?.x5Web?.loadUrl(mLoadUrl)
}
private fun initWebSettings() {
val webSetting = mDataBind?.x5Web?.settings
// 開啓 JS
webSetting?.javaScriptEnabled = true
// 開啓支持插件
webSetting?.pluginsEnabled = true
// 將圖片調整適合 WebView 大小(響應式)
webSetting?.useWideViewPort = true
// 縮放至屏幕大小
webSetting?.loadWithOverviewMode = true
// 支持縮放
webSetting?.setSupportZoom(true)
webSetting?.builtInZoomControls = true
// 隱藏默認縮放控件
webSetting?.displayZoomControls = false
// 支持重新佈局
webSetting?.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
// 開啓多窗口
webSetting?.supportMultipleWindows()
// 不使用緩存
webSetting?.cacheMode = WebSettings.LOAD_NO_CACHE
// 允許訪問文件
webSetting?.allowFileAccess
// 允許通過 JS 打開新窗口
webSetting?.javaScriptCanOpenWindowsAutomatically
// 允許自動加載圖片
webSetting?.loadsImagesAutomatically = true
// 允許定位
webSetting?.setGeolocationEnabled(true)
// 設置默認編碼格式
webSetting?.defaultTextEncodingName = "UTF-8"
// 不顯示水平滾動條
mDataBind?.x5Web?.isHorizontalScrollBarEnabled = false
// 不顯示垂直滾動條
mDataBind?.x5Web?.isVerticalScrollBarEnabled = false
}
private fun initChromeClient() {
// 使用內置瀏覽器打開
mDataBind?.x5Web?.webViewClient = object : WebViewClient() {
/**
* 開始加載網頁
*/
override fun onPageStarted(webView: WebView?, url: String?, bitmap: Bitmap?) {
super.onPageStarted(webView, url, bitmap)
}
/**
* 網頁加載完成
*/
override fun onPageFinished(webView: WebView?, url: String?) {
super.onPageFinished(webView, url)
}
/**
* 網頁加載失敗處理
*/
override fun onReceivedError(webView: WebView?, errorCode: Int, desc: String?, faileUrl: String?) {
super.onReceivedError(webView, errorCode, desc, faileUrl)
}
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
view.loadUrl(url)
return true
}
/**
* Https 處理
*/
override fun onReceivedSslError(webView: WebView?, handler: SslErrorHandler?, sslError: SslError?) {
// 信任所有網址證書
handler!!.proceed()
}
}
mDataBind?.x5Web?.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) {
mDataBind?.progressBar?.progress = newProgress
if (newProgress == 100) {
// newProgress 代表網頁加載進度,到達 100 完成加載
mDataBind?.progressBar?.visibility = View.GONE
}
}
}
}
/**
* 重寫返回 使其在網頁中點擊返回鍵可以依次返回上級
*/
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK && mDataBind?.x5Web?.canGoBack()!!) {
mDataBind?.x5Web?.goBack()
} else {
finish()
}
return false
}
}
一起來看效果演示圖:
有的小夥伴說了,如何確保集成 TBS X5 成功呢?
很 easy,隨便打開網頁,複製顯示小水滴即說明成功,如下所示:
後記
當然,TBS X5 也存在一些問題,例如不支持在線瀏覽 PDF 文件、不支持 64 位,不過暫時還沒有遇到其他的。
iOS 提供的 WebView 相比 Android 可謂良心發現吶,簡直爽的一批~
好了,簡單回顧下 Android 以及 Kotlin,果不其然,好多忘記了,尷尬 😅😅😅
這裏頓時想到雞大大黑黑大臉又要說還是不熟悉,😅😅😅
好吧,好吧,我也要認認真真啦~
朝着雞大大,衝鴨~
經歷 Error
Q 1:net::ERR_CLEARTEXT_NOT_PERMITTED
如下圖所示:
解決方案:
Mainifest 中的 application 添加如下:
android:usesCleartextTraffic="true"
參考地址:
個人公衆號
不定期發佈博文,最近有點忙,感謝老鐵理解,歡迎關注~
參考資料
- TBS X5 官方地址:https://x5.tencent.com/tbs/index.html