三方庫 之 分分鐘集成騰訊 TBS X5 。。。

LZ-Says:想和你喝酒是假,想醉你懷裏是真。

前言

最近一段時間,都是在被前端虐了,還好,談不上遊刃有餘,至少可以實現所需功能,調試起來也不會太過於懵逼。

當然,和大佬相比,還是差距很多。前段時間,因爲個人原因,暫時停滯了前行之路,而今,慢慢拾起,希望努力實現自己想要的。

好久沒碰 Android,今天拿 TBS X5 作爲練手~

TBS X5 瞭解

曾經,在 Android 的世界裏,加載網頁,WebView 首當其衝,但是,當理想遇到顯示,又出現如下情況 (節選自 TBS X5 官方)

  • 傳統系統內核 ( Webview ) 存在適配成本高、不安全、不穩定、耗流量、速度慢、視頻播放差、文件能力差等問題

那麼針對以上提出的問題,我們該怎麼辦呢?

  • 優化?Enmmm,Sorry,打擾了。

  • 第三方開源方案,Enmmm,似乎還是有些問題,應用率以及使用率相對來說有待期待。

  • TBS X5?試試?

那麼 TBS X5 是個什麼鬼?它又是擁有着何樣的才能呢?一起來看~

騰訊瀏覽服務(TBS,Tencent Browsing Service)整合騰訊底層瀏覽技術和騰訊平臺資源及能力,提供整體瀏覽服務解決方案。

而 ta 又具有何方風采呢?爲了省事兒,直接官方盜圖~

  1. 速度快:相比系統 webview 的網頁打開速度有 30+% 的提升;

  2. 省流量:使用雲端優化技術使流量節省 20+%;

  3. 更安全:安全問題可以在 24 小時內修復;

  4. 更穩定:經過億級用戶的使用考驗,CRASH 率低於 0.15%;

  5. 兼容好:無系統內核的碎片化問題,更少的兼容性問題;

  6. 體驗優:支持夜間模式、適屏排版、字體設置等瀏覽增強功能;

  7. 功能全:在 Html5、ES6 上有更完整支持;

  8. 更強大:集成強大的視頻播放器,支持視頻格式遠多於系統 webview;

  9. 視頻和文件格式的支持 x5 內核多於系統內核;

  10. 防劫持是 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 加載頁,簡單說下想法:

  1. Web 頁根據上頁傳遞標誌符進行動態設置加載 URL;
  2. Web 頁加載時,頂部需要有進度條;
  3. 剩下則是 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"

參考地址:

https://stackoverflow.com/questions/52707918/webview-showing-err-cleartext-not-permitted-although-site-is-https

個人公衆號

不定期發佈博文,最近有點忙,感謝老鐵理解,歡迎關注~

參考資料

  1. TBS X5 官方地址:https://x5.tencent.com/tbs/index.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章