点击事件埋点

这篇博客详细介绍了在Android应用中实现点击事件自动埋点的三种方案:使用AspectJ进行AOP织入,通过ASM操作字节码,以及利用AST语法树解析。每个方案都分为多个步骤进行详细讲解,包括创建Gradle插件、定义切面、处理字节码和解析语法树等。此外,还提供了GitHub项目链接供读者深入研究。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TrackAppClick

点击事件自动埋点


App模块

各种点击事件埋点测试

		button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            
            }
        });
        
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {


            }
        });
        
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        ......

track-api模块

TrackAPI

用于客户端进行初始化

    public static TrackAPI init(Application application) {
        synchronized (mLock) {
            if (null == INSTANCE) {
                INSTANCE = new TrackAPI(application);
            }
            return INSTANCE;
        }
    }

    static TrackAPI getInstance() {
        return INSTANCE;
    }

    private TrackAPI(Application application) {
        mDeviceId = getAndroidID(application.getApplicationContext());
        mDeviceInfo = getDeviceInfo(application.getApplicationContext());
    }
    
	客户端这样调用就可以了
	public class MyApplication extends Application {
	    @Override
	    public void onCreate() {
	        super.onCreate();
	
	        initTrackAPI(this);
	    }
	
	    /**
	     * 初始化埋点 SDK
	     *
	     * @param application Application
	     */
	    private void initTrackAPI(Application application) {
	        TrackAPI.init(application);
	    }
	}
TrackHelper

用于gradle plugin调用

    public static void trackViewOnClick(View view) {
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("$element_type", TrackPrivateAPI.getElementType(view));
            jsonObject.put("$element_id", TrackPrivateAPI.getViewId(view));
            jsonObject.put("$element_content", TrackPrivateAPI.getElementContent(view));

            Activity activity = TrackPrivateAPI.getActivityFromView(view);
            if (activity != null) {
                jsonObject.put("$activity", activity.getClass().getCanonicalName());
            }

            TrackAPI.getInstance().track("$AppClick", jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
TrackPrivateAPI

一些track-api模块内部调用的api,用于value值

TrackViewOnClick

用于对自定义方法埋点(对xml中的onClick方法注解,使其也能埋点)

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackViewOnClick {
}

aspectJ方案

aspectjplugin模块

Step1:创建groovy目录,并新建一个实现Plugin接口的类(该类apply方法中会指定执行一些task,我会指定其在项目编译时执行ajc编译织入增强(Advice)代码)。

class AspectJPlugin implements Plugin<Project> {
    void apply(Project project) {
        final def log = project.logger

        project.dependencies {
            implementation 'org.aspectj:aspectjrt:1.8.10'
        }

        if (project.android.hasProperty('applicationVariants')) {
            project.android.applicationVariants.all { variant ->
                JavaCompile javaCompile = variant.javaCompile

                javaCompile.doLast {
                    String[] args = [
                            "-showWeaveInfo",
                            "-1.7",
                            "-inpath", javaCompile.destinationDir.toString(),
                            "-aspectpath", javaCompile.classpath.asPath,
                            "-d", javaCompile.destinationDir.toString(),
                            "-classpath", javaCompile.classpath.asPath,
                            "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)
                    ]
                    MessageHandler handler = new MessageHandler(true);
                    new Main().run(args, handler);

                    for (IMessage message : handler.getMessages(null, true)) {
                        switch (message.getKind()) {
                            case IMessage.ABORT:
                            case IMessage.ERROR:
                            case IMessage.FAIL:
                                log.error message.message, message.thrown
                                break;
                            case IMessage.WARNING:
                                log.warn message.message, message.thrown
                                break;
                            case IMessage.INFO:
                                log.info message.message, message.thrown
                                break;
                            case IMessage.DEBUG:
                                log.debug message.message, message.thrown
                                break;
                        }
                    }
                }
            }
        }

        if (project.android.hasProperty('libraryVarian
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值