BusUtilsClassVisitor.java 3.0 KB
Newer Older
B
Blankj 已提交
1 2 3 4 5 6 7 8
package com.blankj.bus;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.AdviceAdapter;

B
Blankj 已提交
9
import java.util.List;
B
Blankj 已提交
10 11 12 13
import java.util.Map;

/**
 * <pre>
B
Blankj 已提交
14
 *     author: Blankj
B
Blankj 已提交
15 16 17 18 19 20 21
 *     blog  : http://blankj.com
 *     time  : 2019/07/09
 *     desc  :
 * </pre>
 */
public class BusUtilsClassVisitor extends ClassVisitor {

B
Blankj 已提交
22
    private Map<String, List<BusInfo>> mBusMap;
B
Blankj 已提交
23
    private String                     mBusUtilsClass;
B
Blankj 已提交
24

B
Blankj 已提交
25
    public BusUtilsClassVisitor(ClassVisitor classVisitor, Map<String, List<BusInfo>> busMap, String busUtilsClass) {
B
Blankj 已提交
26
        super(Opcodes.ASM5, classVisitor);
B
Blankj 已提交
27
        mBusMap = busMap;
B
Blankj 已提交
28
        mBusUtilsClass = busUtilsClass.replace(".", "/");
B
Blankj 已提交
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        if (!"init".equals(name)) {
            return super.visitMethod(access, name, descriptor, signature, exceptions);
        }
        // 往 init() 函数中写入
        if (cv == null) return null;
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        mv = new AdviceAdapter(Opcodes.ASM5, mv, access, name, descriptor) {

            @Override
            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                return super.visitAnnotation(desc, visible);
            }

            @Override
            protected void onMethodEnter() {
                super.onMethodEnter();
            }

            @Override
            protected void onMethodExit(int opcode) {
                super.onMethodExit(opcode);
B
Blankj 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
                for (Map.Entry<String, List<BusInfo>> busEntry : mBusMap.entrySet()) {
                    List<BusInfo> infoList = busEntry.getValue();
                    if (infoList.size() != 1) continue;
                    BusInfo busInfo = infoList.get(0);
                    if (!busInfo.isParamSizeNoMoreThanOne) continue;
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitLdcInsn(busEntry.getKey());
                    mv.visitLdcInsn(busInfo.className);
                    mv.visitLdcInsn(busInfo.funName);
                    if (busInfo.paramsInfo.size() == 1) {
                        mv.visitLdcInsn(busInfo.paramsInfo.get(0).className);
                        mv.visitLdcInsn(busInfo.paramsInfo.get(0).name);
                    } else {
                        mv.visitLdcInsn("");
                        mv.visitLdcInsn("");
                    }
                    mv.visitInsn(busInfo.sticky ? ICONST_1 : ICONST_0);
                    mv.visitLdcInsn(busInfo.threadMode);
B
Blankj 已提交
72
                    mv.visitMethodInsn(INVOKESPECIAL, mBusUtilsClass, "registerBus", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V", false);
B
Blankj 已提交
73 74 75 76 77 78
                }
            }
        };
        return mv;
    }
}