前言
因为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")
}
}
}