WebView 使用與優化

1.前言

之前開發過一款軟件是 Android 原生 + Vue,裏面就涉及到使用 WebView 加載 web 的頁面。對於 Android 端來說,涉及到的技術就是 Android 原生調用 Web 以及 Web 如何調用 Android 原生代碼。此篇文章用於記錄 WebView 的一些使用方法,以及如何對 WebView 進行優化。

2. WebView 使用

2.1 WebView 的創建

不在 xml 中定義 WebView,在需要的時候在 Activity 中創建,並且 context 使用 ApplicationContext

        var params = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        mWebView = WebView(applicationContext)
        mWebView.layoutParams = params

2.2 對 WebView 進行配置和管理 

var webSettings = mWebView.settings
// 如果訪問的頁面中要與Javascript交互,則webview必須設置支持Javascript
webSettings.javaScriptEnabled = true
// 隱藏滾動條
mWebView.isHorizontalScrollBarEnabled = false
mWebView.isVerticalScrollBarEnabled = false

2.3 加載 url

a. 加載網頁

webView.loadUrl("https://www.baidu.com/")

b. 加載 apk 中的 html 頁面

mWebView.loadUrl("file:///android_asset/xxx.html#/" );

2.4 WebView與JavaScript 的交互

頁面中要與Javascript交互,則 webview 必須設置支持 Javascript:

var webSettings = mWebView.settings
webSettings.javaScriptEnabled = true

2.4.1 Android 調用 JS 代碼:

通過 WebView 的 loadUrl() 方法:

js 端:

通過 WebView 的 evaluateJavascript() 方法:

        mWebView.evaluateJavascript("javascript:callJS()", ValueCallback {
            //此處爲 js 返回的結果
        })

兩種方法的對比:

2.4.1 JS 調用 Android 代碼:

通過 WebView 的 addJavascriptInterface() 方法

        // 添加js接口
        mWebView.addJavascriptInterface(WebInterface(), "zzw")
class WebInterface {
    @JavascriptInterface
    fun setTaskData(taskData: String?, finishPage: Boolean) {
        //TODO
    }
}

js 端:

this.$setTaskData(JSON.stringify(this.conditionData), true);

3. WebView 性能優化

3.1 WebView 初始化

class SecondActivity : AppCompatActivity() {
    private lateinit var mRoot: FrameLayout
    private var startTime = 0L
    private var endTime = 0L
    private lateinit var mWebView: WebView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startTime = System.currentTimeMillis()
        setContentView(R.layout.activity_second)
        mRoot = findViewById(R.id.root)
    }

    override fun onResume() {
        super.onResume()
        endTime = System.currentTimeMillis()
        Log.e("zzw", "Total=" + (endTime - startTime))
    }

}

這樣的一個頁面,在 xml 中只有一個 FrameLayout,通過這樣記錄啓動頁面耗時:

2020-07-06 15:56:05.201 30236-30236/cn.zzw.template.webviewdemo E/zzw: Total=59
2020-07-06 15:56:20.826 30236-30236/cn.zzw.template.webviewdemo E/zzw: Total=48
2020-07-06 15:56:36.182 30236-30236/cn.zzw.template.webviewdemo E/zzw: Total=51
2020-07-06 15:56:53.434 30328-30328/cn.zzw.template.webviewdemo E/zzw: Total=46
2020-07-06 15:57:26.426 30394-30394/cn.zzw.template.webviewdemo E/zzw: Total=34

這是五次的啓動頁面時間,都是在 50ms 上下。

在 Activity 中動態添加一個 WebView ,並且這個 WebView 沒有加載任何東西:

class SecondActivity : AppCompatActivity() {
    private lateinit var mRoot: FrameLayout
    private var startTime = 0L
    private var endTime = 0L
    private lateinit var mWebView: WebView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startTime = System.currentTimeMillis()
        setContentView(R.layout.activity_second)
        mRoot = findViewById(R.id.root)
        var params = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        mWebView = WebView(applicationContext)
        mWebView.layoutParams = params
        mRoot.addView(mWebView)

    }

    override fun onResume() {
        super.onResume()
        endTime = System.currentTimeMillis()
        Log.e("zzw", "Total=" + (endTime - startTime))
    }

}

啓動頁面耗時:

2020-07-06 16:02:08.999 30932-30932/cn.zzw.template.webviewdemo E/zzw: Total=349
2020-07-06 16:02:36.200 31052-31052/cn.zzw.template.webviewdemo E/zzw: Total=377
2020-07-06 16:02:54.943 31165-31165/cn.zzw.template.webviewdemo E/zzw: Total=322
2020-07-06 16:04:26.142 31445-31445/cn.zzw.template.webviewdemo E/zzw: Total=372
2020-07-06 16:04:44.201 31555-31555/cn.zzw.template.webviewdemo E/zzw: Total=450

這是五次重新運行並啓動頁面時間,都是在 350~450ms。而如果第一次啓動後,退出頁面,再次進入頁面的時間:

2020-07-06 16:12:47.124 31948-31948/cn.zzw.template.webviewdemo E/zzw: Total=378
2020-07-06 16:12:54.902 31948-31948/cn.zzw.template.webviewdemo E/zzw: Total=82
2020-07-06 16:12:58.295 31948-31948/cn.zzw.template.webviewdemo E/zzw: Total=46
2020-07-06 16:13:05.219 31948-31948/cn.zzw.template.webviewdemo E/zzw: Total=47
2020-07-06 16:13:09.002 31948-31948/cn.zzw.template.webviewdemo E/zzw: Total=45

從上面可以看出 webView 的初始化是很耗時間的, 這是因爲需要加載 Webview 內核,這是一個重量級的操作,內核是以apk的形式存在。而內核加載後是共享的,因此後續的初始化時間就很少了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章