背景
由於網絡或者其他原因,用戶在訪問我們的網頁的時候出現加載白屏空屏問題,希望移動端去檢測到這個白屏之后給到一些優化操作。這里重點說下Android的兩種白屏檢測方式。
檢測方式
1.通過在網頁加載結束之后,對Webview截屏分析截屏頁面的像素,如果白色或者同色的像素點較多,則認為是白屏。下面是實現方式
private fun checkIsEmptyPage( bitmap: Bitmap?, succeed: () -> Unit, error: () -> Unit, completed: () -> Unit ) { if (bitmap == null) { error.invoke() completed.invoke() return@checkIsEmptyPage } GlobalScope.launch(Dispatchers.IO) { val width = bitmap.width val height = bitmap.height for (x in 0 until width) { for (y in 0 until height) { if (bitmap.getPixel(x, y) == -1) { whitePixelCount++ } } } if (whitePixelCount > 0) { rate = whitePixelCount * 100f / width / height } //檢測發現不是白屏,開始二次檢測 if (rate <= threshold){ val colorMap = mutableMapOf<Int,Int>() for (x in 0 until width) { for (y in 0 until height) { val times = colorMap[bitmap.getPixel(x, y)]?:0 val timesAdd = times+1 colorMap[bitmap.getPixel(x,y)] = timesAdd } } var maxTimes = -1 colorMap.forEach { if (maxTimes<it.value){ maxTimes = it.value } } if (maxTimes>0){ rate = maxTimes * 100f / width / height } } bitmap.recycle() GlobalScope.launch(Dispatchers.Main) { if (rate > threshold) { //page empty error?.invoke() } else { succeed?.invoke() } completed.invoke() } }.bindLifeCycle(lifecycle) }
獲取到Webview截屏的bitmap然后對其進行一個像素點掃描,代碼比較簡單這里貼出主要代碼。說一下這種方式的利弊,這種方式適合正常頁面的元素較多,內容比較豐富的情況,如果這個頁面只有幾個文字的話也容易被誤檢測為白屏,檢測效果並不是特別好。容易出現誤判。並不推薦。
2.通過對網頁內容的分析比對
這里對網頁內容進行分析又兩種方式一個是JS注入的方式,打印出網頁的內容。這個方式對頁面又侵入性,不太推薦。這里不多介紹,那么還有一種方式,書簽的形式,安卓的瀏覽器其實自帶又書簽的功能,他能將網頁離線暫存到本地。我們可以通過這個方式獲取到網頁的內容。順道提一下,這個書簽在iOS平台是沒有的,不得不說android的webview是比iOS的功能強大一些。
webview?.saveWebArchive(view.context.filesDir.path+"/tempCollection.mht",false ) { val file = File(it) if ( file.exists()){ val text = file.readText() Log.e("WebViewHelper",text.toString() } file.delete() }
saveWebArcchive方法是異步的,在保存網頁之后回掉接口會返回你傳入的路徑如果這個路徑不為空那么說明當前webview加載的內容被存了下來。或者內容之后你可以通過的html做判斷或者對這個file內容做對比,從而確定你的網頁當前是否是白屏沒加載出東西了。