背景
由于网络或者其他原因,用户在访问我们的网页的时候出现加载白屏空屏问题,希望移动端去检测到这个白屏之后给到一些优化操作。这里重点说下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内容做对比,从而确定你的网页当前是否是白屏没加载出东西了。