fresco大图监控方案

/ 0评 / 0

前言

因为fresco库没有自动根据控件大小裁剪图片,所以需要手动监控是否存在大图

实现

通过lancet框架进行插桩

@Insert("reportSuccess")
@TargetClass("com.facebook.drawee.controller.AbstractDraweeController")
private <T> void reportSuccess(String id, @Nullable T image, @Nullable DataSource<T> dataSource) {
    Origin.callVoid();
    PerfController.INSTANCE.reportSuccess(id, image, dataSource);
}

上报代码如下

object PerfController {
    private const val TAG = "PerfController"

    private const val MAX_BYTE_STATIC = 2000 * 2000
    private const val MAX_BYTE_GIF = 25 * 1080 * 500

    private val urlSet = mutableSetOf<String>()

    private val enable by lazy {
        checkEnableAndReset()
    }

    @SuppressLint("AndroidLogDeprecated")
    fun reportSuccess(id: String?, image: Any?, dataSource: Any?) {
        if (!enable) {
            return
        }
        kotlin.runCatching {
            var p = 0f
            if (dataSource is DataSource<*>) {
                p = dataSource.progress
            }
            if (p < 1) {
                return
            }
            if (image is CloseableReference<*>) {
                val valid = CloseableReference.isValid(image)
                if (valid) {
                    val any = image.get()
                    var url: String? = null
                    var w: Int? = null
                    var h: Int? = null
                    var f: Int? = null
                    if (any is CloseableImage) {
                        url = any.extras[ProducerContext.ExtraKeys.SOURCE_URI]?.toString()
                        w = any.extras[ProducerContext.ExtraKeys.ENCODED_WIDTH] as? Int
                        h = any.extras[ProducerContext.ExtraKeys.ENCODED_HEIGHT] as? Int
                    }
                    if (any is CloseableAnimatedImage) {
                        f = any.image?.frameCount ?: 1
                    }
                    onlyDebug {
                        Log.i(TAG, "url = $url,w=$w,h=$h,f=$f,p=$p")
                    }
                    report(url ?: "", w ?: 1, h ?: 1, f ?: 1)
                }
            }
        }
    }

    fun updateConfig(enable: Boolean) {
        MMkvUtils.putBoolean("PerfController", "PerfController", enable)
    }

    private fun checkEnableAndReset(): Boolean {
        val boolean = MMkvUtils.getBoolean("PerfController", "PerfController", false)
        updateConfig(false)
        return boolean
    }

    private fun report(url: String, w: Int, h: Int, f: Int) {
        if (!url.startsWith("http")) {
            return
        }

        val size = w * h * f
        val type = url.substringAfterLast(".")

        if (type != "gif" && size < MAX_BYTE_STATIC) {
            return
        }

        if (type == "gif" && size < MAX_BYTE_GIF) {
            return
        }

        if (urlSet.contains(url)) {
            return
        }
        urlSet.add(url)

        val map = ConcurrentHashMap<String, String>().apply {
            put("url", url)
            put("topui", UiKey.getTopUiClass())
            put("key", UiKey.getTopUi())
            put("w", w.toString())
            put("h", h.toString())
            put("f", f.toString())
            put("size", size.toString())
            put("type", type)
        }
        //TODO 上报
        }
        onlyDebug {
            Log.i(TAG, ">>>> url = $url,w=$w,h=$h,f=$f")
        }
    }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注