EventBus 的源码集成实践,如何将EventBus源码修改包名,并将atp集成到自己的项目中

需求背景

  • 最近做了个需求,是需要将EventBus集成到自己的项目中,由于我们是做SDK的,提供给用户的库不能有太多的第三方依赖库,否则别人接入你的SDK的时候容易发送冲突,我们将不使用gradle进行依赖,而转用EventBus源码的方式,为了提升EventBus的执行效率,还引入了apt,下面我们来说下具体的实践吧

了解EventBus

EventBus源码集成

  • 我们使用git clone  https://github.com/greenrobot/EventBus.git将源码copy到本地,然后使用Android studio 打开,然后将需要用到的源码拷贝的我们定义好的项目包名下
  •  在我们的项目里面建一个模块,比如就叫lcqlib,然后将EventBus上面两个modul里面的源码拷贝到 com.lcq.lcqlib.msgbus包路径下
  • 然后我们需要将报的红色异常给解决掉,下面提供一个快速的查找替换方式
  • 这样可以找到所有使用的地方进行全部替换 
  • 使用Replace All 就可以替换所有的代码了,我们再找到AndroidDependenciesDetector类
  • 然后搜索“org.greenrobot.eventbus”将这个位置替换为“com.lcq.lcqlib.msgbus.org.greenrobot.eventbus”,要不后面执行时会抛异常
  • 然后我们再assemble一下module,能正常编译过就可以了,为方便使用,我们有比较将这个库打包一下,由于只有源码没有资源文件,我们直接打包成jar包吧,这个jar在后面我们说apt的时候也会用到
  • 要方便的生成jar并且定义名称,最好的方式就是写个task运行最好了
  • makejar就是用来生成我们所需要jar的
    task makeJar(group: 'build', type: Copy) {
        String libName = "${project.name}_3.3.2.jar"
        delete "build/libs/${libName}"
        from('build/intermediates/aar_main_jar/release')
        into('build/libs/')
        include('classes.jar')
        rename('classes.jar', libName)
    }
    makeJar.dependsOn(build)

    我们执行makejar的task会生成一个lcqlib_3.3.2.jar已备后续使用

EventBus的APT源码集成

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

android {

    defaultConfig {

        javaCompileOptions {

            annotationProcessorOptions {

                arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ]

            }

        }

    }

}

dependencies {

    def eventbus_version = '3.2.0'

    implementation "org.greenrobot:eventbus:$eventbus_version"

    annotationProcessor "org.greenrobot:eventbus-annotation-processor:$eventbus_version"

}

  • 当然,这样的方式对于我们源码的使用方式肯定是不行的,EventBus的apt是针对自己的源码来进行注解实现的,现在我们已经将源码包名都给改了肯定是不行的,现在我们就需要自己模仿EventBus的APT源码进行实现了,其实很简单,下面我们来实现以下
  • 首先找到EventBus源码项目里面的EventBusAnnotationProcessor工程,然后将里面的源码拷贝出来
  • 我们在自己的项目里面建一个java library 类型的module,然后将 EventBusAnnotationProcessor的源码拷贝进来
  •  可以看到报红了,里面就一个类,我们看看报红的地方
  • 应该是缺少某些依赖并且里面的import org.greenrobot.eventbus.Subscribe需要替换为我们自己定义的类,将上面生成的lcqlib_3.3.2.jar拷贝到lcqlib的lib目录下,import依赖为com.lcq.lcqlib.msgbus.org.greenrobot.eventbus.Subscribe和com.lcq.lcqlib.msgbus.org.greenrobot.eventbus.ThreadMode,
  • 然后我们再看看EventBusAnnotationProcessor 类的源码,搜索“import org.greenrobot.eventbus.”,我们需要将这个代码替换成“com.lcq.lcqlib.msgbus.org.greenrobot.eventbus.”,这样做的目的是使用我们自己源码里面的类,否则后面会报找不类的异常
  •  修改后的代码
  • 还需修改下这个注解的地方,也改成我们源码的包名
  • 修改完源码后我们需要将EventBusAnnotationProcessor这个类的带包名全路径配置到res/META-INFO/services/javax.annotation.processing.Processor这个文件中,这个很重要,如果不配置,后面使用apt的时候将不起作用,如下图所示
  • 接下来还需要在lcqapt模块build.gradle中配置apt所依赖的第二三方库了。如下
    apply plugin: 'java'
    
    group = rootProject.group
    version = rootProject.version
    
    java.sourceCompatibility = JavaVersion.VERSION_1_8
    java.targetCompatibility = JavaVersion.VERSION_1_8
    
    dependencies {
        implementation files('libs/lcqlib_3.3.2.jar')
        implementation 'de.greenrobot:java-common:2.3.1'
    
        // Generates the required META-INF descriptor to make the processor incremental.
        def incap = '0.2'
        implementation "net.ltgt.gradle.incap:incap:$incap"
        implementation "net.ltgt.gradle.incap:incap-processor:$incap"
        annotationProcessor "net.ltgt.gradle.incap:incap-processor:$incap"
    }
    
    sourceSets {
        main {
            java {
                srcDir 'src'
            }
            resources {
                srcDir 'res'
            }
        }
    }
    
    javadoc {
        title = "EventBus Annotation Processor ${version} API"
        options.bottom = 'Available under the Apache License, Version 2.0 - <i>Copyright &#169; 2015-2020 <a href="https://greenrobot.org">greenrobot.org</a>. All Rights Reserved.</i>'
    }
    
    task javadocJar(type: Jar, dependsOn: javadoc) {
        archiveClassifier.set("javadoc")
        from 'build/docs/javadoc'
    }
    
    task sourcesJar(type: Jar) {
        archiveClassifier.set("sources")
        from sourceSets.main.allSource
    }
    apply plugin: 'com.github.johnrengelman.shadow'
    shadowJar {
        manifest {  //main方法所在的类
        }
    }
    
    
    
  •  dependencies{} 里面配置了用到的依赖库
  • sourceSets 里面配置了 “src”和“res”路径
  • apply plugin: 'com.github.johnrengelman.shadow' 用来将生成的apt 打包成一个jar包,使用这个gradle插件还需要在根目录的build.gradle做如下配置
    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    buildscript {
        repositories {
            google()
            jcenter() //shadow插件用到的仓库
            mavenCentral()
        }
        dependencies {
            classpath "com.android.tools.build:gradle:7.0.3"
    
            //shadow 插件的配置
            classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.0'
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
  • 配置好后我们执行下shadowJar task,会生成我们需要的apt 插件jar包
  •  我们把生成的lcqapt.jar拷贝到需要使用的模块或者项目中,然后进行配置就能使用了

如何使用自己构建的EventBus和apt库

  • 上面的一系列操作,主要新建了lcqlib和lcqapt两个库,生成的jar包产物为lcqlib_3.3.2.jar和lcqapt.jar,下面我们就来在demo中看下如何使用
  • 首先肯定是需要在项目中引入我们生成的jar包了,将lcqlib_3.3.2.ja拷贝到libs目录,将lcqapt.jar拷贝到libs_apt目录,lcqapt.jar不拷贝到libs目录主要是为了不让其生成apk或者aar包的时候编译进行去,这个只是用来为我们生成代码的,只在编译阶段使用
  • 然后在app的build.gradle里面配置依赖,以及要生成的类
    plugins {
        id 'com.android.application'
    }
    
    android {
        compileSdk 30
    
        defaultConfig {
            applicationId "com.lcq.lcqeventbus"
            ...
    
            javaCompileOptions {
                annotationProcessorOptions {
                    //指定辅助索引类的名称和包名 EventBus config
                    arguments = [eventBusIndex: 'com.lcq.lcqeventbus.MyEventBusIndex']
                }
            }
        }
    
        ...
    }
    
    dependencies {
        ...
    
        //EventBus config
        api files("libs/lcqlib_3.3.2.jar")
        annotationProcessor files("/libs_apt/lcqapt.jar")
    }
  • 配置完成后,就需要编写代码了,我们再app模块里面的MainActivity里进行测试,编写如下代码,如果对EventBus的使用还不清楚,可以去官网学习下
    package com.lcq.lcqeventbus;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Toast;
    
    import com.lcq.lcqlib.msgbus.org.greenrobot.eventbus.EventBus;
    import com.lcq.lcqlib.msgbus.org.greenrobot.eventbus.Subscribe;
    
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            EventBus.builder()
                    .addIndex(new MyEventBusIndex())
                    .installDefaultEventBus();
            EventBus.getDefault().register(this);
        }
    
        @Subscribe
        public void handleMsg(String msg) {
            Toast.makeText(this, "msg:" + msg, Toast.LENGTH_LONG).show();
        }
    
        public void onClick(View v) {
            EventBus.getDefault().post("HELLO,EventBus APT");
        }
    }
  • 运行后的结果,如下:

    总结: 整个过程还是比较繁琐的,也有很多容易出错的地方,还用到了很多第三方gradle插件或脚本,不过只要搭建好了这个框架,后期基本就不会怎么变化了,使用起来和原生的EventBus 几乎一模一样,达到了修改源码包名的目的,这样发出去的SDK也不会担心和接入方的有冲突了,还可以根据自己的需求修改EventBus源码,这样就把EventBus的轮子集成到我们自己项目中了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值