从事Android开发的同学可能都会有这个需求,最近在学ASM相关的知识,拿这个想法练了一下手。大体思路是这样的,通过字节码Hook所有onClick(View view)方法,通过view.setTag(key,value)设置tag为当前时间戳,这样再次点击的时候就有一个时间差,通过对这个时间差,可以过滤掉多余的响应操作。
首先我们看一下lamba表达式和普通的setOnClickListener编译完是什么样的。
由截图可以看到不管我们以哪种方式设置监听点击,最终都是一个实现View.OnClickListener接口的静态内部类,由此我们可以Hook所有实现了View.OnClickListener接口的类中的名字为onClick,签名为(Landroid/view/View;)V的方法,在方法前面插入我们想要的代码。具体实现是这样的:
定义一个ClassVisitor:
class MutiClickHandleVisitor(classVisitor: ClassVisitor): ClassVisitor(Opcodes.ASM5,classVisitor) {
private val classFullName = "android/view/View\$OnClickListener"
private var isMatchClass = false
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,