Bootstrap

Android集成腾讯X5浏览器内核库

一、相关配置

1. 相关地址

https://x5.tencent.com/

2.引入SDK

在build.gradle中dependencies引入sdk

 api 'com.tencent.tbs.tbssdk:sdk:43903'

build.gradle中的andorid->defaultConfig中

   ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }

3. AndroidManifest配置

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

二、Application中初始化内核

class APPAplication : Application() {
    override fun onCreate() {
        super.onCreate()
        //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
        val cb: QbSdk.PreInitCallback =
            object : QbSdk.PreInitCallback {
                override fun onViewInitFinished(arg0: Boolean) {
                    //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                }

                override fun onCoreInitFinished() {
                }
            }
        //x5内核初始化接口
        QbSdk.initX5Environment(applicationContext, cb)
    }
}

三、代码实现

1. 自定义带ProgressBar的WebView

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.AbsoluteLayout
import android.widget.ProgressBar
import com.huang.myapplication.R
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

internal class ProgressWebview : WebView {
    //进度条
    private var progressbar: ProgressBar? = null
    //进度条的高度,默认5px
    private val progressHeight = 5

    constructor(context: Context) : super(context) {
        initView(context)
    }

    constructor(context: Context, attributeSet: AttributeSet?) : super(
        context,
        attributeSet
    ) {
        initView(context)
    }

    private fun initView(context: Context) {

        //开启js脚本支持
        settings.javaScriptEnabled = true

        //创建进度条
        progressbar = ProgressBar(
            context, null,
            android.R.attr.progressBarStyleHorizontal
        )
        //设置加载进度条的高度
        progressbar!!.layoutParams = AbsoluteLayout.LayoutParams(
            LayoutParams.MATCH_PARENT,
            progressHeight,
            0,
            0
        )

        var drawable = context.getResources().getDrawable(R.drawable.progress_bar_states);
        progressbar!!.setProgressDrawable(drawable);

        //添加进度到WebView
        addView(progressbar)

        //适配手机大小
        settings.useWideViewPort = true
        settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
        settings.loadWithOverviewMode = true
        settings.setSupportZoom(true)
        settings.builtInZoomControls = true
        settings.displayZoomControls = false
        webChromeClient = WVChromeClient()
        webViewClient = WVClient()
    }

    //进度显示
    private inner class WVChromeClient : WebChromeClient() {
        override fun onProgressChanged(
            view: WebView,
            newProgress: Int
        ) {
            if (newProgress == 100) {
                progressbar!!.visibility = View.GONE
            } else {
                if (progressbar!!.visibility == View.GONE) progressbar!!.visibility = View.VISIBLE
                progressbar!!.progress = newProgress
            }
            if (mListener != null) {
                mListener!!.onProgressChange(view, newProgress)
            }
            super.onProgressChanged(view, newProgress)
        }
    }

    private inner class WVClient : WebViewClient() {
        override fun shouldOverrideUrlLoading(
            view: WebView,
            url: String
        ): Boolean {
            //在当前Activity打开
            view.loadUrl(url)
            return true
        }

        override fun onReceivedSslError(
            view: WebView,
            handler: SslErrorHandler,
            error: SslError
        ) {
            //https忽略证书问题
            handler.proceed()
        }

        override fun onPageFinished(
            view: WebView,
            url: String
        ) {
            progressbar!!.visibility = View.GONE
            if (mListener != null) {
                mListener!!.onPageFinish(view)
            }
            super.onPageFinished(view, url)
        }
    }

    private var mListener: onWebViewListener? = null
    fun setOnWebViewListener(listener: onWebViewListener?) {
        mListener = listener
    }

    //进度回调接口
    interface onWebViewListener {
        fun onProgressChange(
            view: WebView?,
            newProgress: Int
        )

        fun onPageFinish(view: WebView?)
    }
}

2. activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.huang.myapplication.ui.ProgressWebview
        android:id="@+id/progress_web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

3. MainActivity

class MainActivity : AppCompatActivity() {
    val url = "https://debugtbs.qq.com/"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val webSetting: WebSettings = progress_web_view.getSettings()
        webSetting.allowFileAccess = true
        webSetting.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
        webSetting.setSupportZoom(true)
        webSetting.builtInZoomControls = true
        webSetting.useWideViewPort = true
        webSetting.setSupportMultipleWindows(false)
        webSetting.setAppCacheEnabled(true)
        webSetting.domStorageEnabled = true
        webSetting.javaScriptEnabled = true
        webSetting.setGeolocationEnabled(true)
        webSetting.setAppCacheMaxSize(Long.MAX_VALUE)
        webSetting.setAppCachePath(getDir("appcache", 0).path)
        webSetting.databasePath = getDir("databases", 0).path
        webSetting.setGeolocationDatabasePath(
            getDir("geolocation", 0)
                .path
        )
        webSetting.pluginState = WebSettings.PluginState.ON_DEMAND
        progress_web_view.loadUrl(url)
        CookieSyncManager.createInstance(this)
        CookieSyncManager.getInstance().sync()

        progress_web_view.setOnWebViewListener(object : onWebViewListener {
            override fun onProgressChange(view: WebView?, newProgress: Int) {
                Log.d("app","onProgressChange=="+newProgress)
            }

            override fun onPageFinish(view: WebView?) {
                Log.d("app","onPageFinish==")
            }

        })

    }


    override fun onResume() {
        super.onResume()
        progress_web_view.onResume()
    }

    override fun onPause() {
        super.onPause()
        progress_web_view.onPause()
    }
}

;