eventbus的使用(三)简洁易懂--EventBus3.0,如何使用annotationProcessor生成索引类

eventbus可以让我们在不同的页面不同的组件之间传递消息,代码简介,使用方便并且可以将发送者和接受者解耦。

关于EventBus2.0的使用可以参考我的另外两篇博客:

eventbus的使用(一)简洁易懂 - 秦时明月 - CSDN博客
https://blog.csdn.net/baidu_31093133/article/details/51726745
eventbus的使用(二)简洁易懂 - 秦时明月 - CSDN博客
https://blog.csdn.net/baidu_31093133/article/details/51727135

本篇博客来说说EventBus3.0的使用O(∩_∩)O

1、EventBus2.0和3.0的区别
1.1

首先是性能上的区别,3.0的反射效率比2.x要低1~3倍,但是开启了索引系统的3.0速度要比2.x快很多,所以我们在使用3.0的时候通常都会开启索引系统。
2.x采用的是运行时注解,运行时注解很大基础上是依赖于java的反射机制实现的,而运行时注解是在运行时使用反射,并且会在反射的过程中会对注册的类的所有的方法进行扫描,所以是耗费性能的,这在一些低端机上尤为明显。
3.0采用的是编译时注解,在java文件编译生产.class文件的时候就已经创建出需要的类和索引关系,并将索引关系编译到apk中,这就比运行的时候再动态的使用反射速度要快。
除了两种注解方式的性能差异外,3.0还加入了对象池缓存并做了一些优化,来减少创建对象的开销。

1.2

第二点是书写方式的区别EventBus有三个主要组成部分:Publisher(事件发布者)、Event(事件)、Subscriber(事件订阅者),工作流程就是发布者发布事件给订阅者
EventBus3.0的事件发布者和事件的书写方式是一致的,最重要的区别在于订阅者。
2.0的订阅者只提供了四个函数onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync并且只能用这四个函数来接受事件。
而3.0的接受方法是自己随意书写的,只需要在方法上添加需要的注解即可,下面我们通过实际使用来体会一下。

2、EventBus3.0的使用

1、导入eventbus
在gradle里面配置

implementation 'org.greenrobot:eventbus:3.1.1'

在同一个activity里:
1、在创建页面的时候注册eventbus
2、在销毁页面的时候注销eventbus
3、使用eventbus.post发送消息
4、消息是一个Object对象

首先我们创建一个类作为事件

public class ClickEvent {
}

接下来是activity的代码

public class MainActivity extends AppCompatActivity {

    private Button btnSend;
    private TextView tvReceive;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
		//在接受消息的activity里注册eventbus
        EventBus.getDefault().register(this);

        btnSend = (Button) findViewById(R.id.btn_send);
        tvReceive = (TextView) findViewById(R.id.tv_receive);

        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            //使用post发送事件
                EventBus.getDefault().post(new ClickEvent());
            }
        });
    }

	//接受消息
    @Subscribe
    public void onReceiveClickEvent(ClickEvent clickEvent) {
        tvReceive.append("收到一条消息\n");
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        //页面销毁的时候注销eventbus
        EventBus.getDefault().unregister(this);
    }

效果图:

eventbus3.0

我们每点击一次按钮就会发送一次事件

接下来我们测试一下在不同的页面传递数据

我们创建一个ReceiveEventActivity,在这个activity里接受MainActivity发出的事件

效果图:
eventbus3.0

在MainActivity里发了6次事件,在ReceiveEventActivity里接受了6次
代码如下:

public class ReceiveEventActivity extends AppCompatActivity {
    private TextView tvReceive;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_receive_event);
        //注册eventbus
        EventBus.getDefault().register(this);
        tvReceive = (TextView) findViewById(R.id.tv_receive);
        findViewById(R.id.btn_jump).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(ReceiveEventActivity.this, MainActivity.class));
            }
        });
    }

    //接受事件
    @Subscribe
    public void onReceiveClickEvent(ClickEvent clickEvent) {
        tvReceive.append("ReceiveEventActivity 收到一条消息\n");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //注销eventbus
        EventBus.getDefault().unregister(this);
    }
}

可以发现,eventbus使用起来很方便很简单

接下来介绍一下eventbus的线程

    //接受事件
    @Subscribe//在这里指定线程
    public void onReceiveClickEvent(ClickEvent clickEvent) {
        tvReceive.append("ReceiveEventActivity 收到一条消息\n");
    }

我们在接受事件的函数上使用了@Subscribe描述符
###我们可以指定接受事件的线程,一共有四种类型:

//与发送事件运行在同一个线程(默认的线程类型)
@Subscribe(threadMode = ThreadMode.POSTING)

// 在主线程中运行也就是UI线程
@Subscribe(threadMode = ThreadMode.MAIN)

// 在后台线程中运行
@Subscribe(threadMode = ThreadMode.BACKGROUND)

// 在另外的独立的线程中执行
@Subscribe(threadMode = ThreadMode.ASYNC)

大家可以自己做实验验证一下哦

###另外我们还可以指定接受事件的优先级
上面的例子中我在ReceiveEventActivity和MainActivity里都接受了事件,我们可以给这两个接受者指定优先级。


ReceiveEventActivity里:

    //接受事件
    @Subscribe(priority = 2)
    public void onReceiveClickEvent(ClickEvent clickEvent) {
        tvReceive.append("ReceiveEventActivity 收到一条消息\n");
    }

MainActivity里:
	//接受事件
    @Subscribe(priority = 1)
    public void onReceiveClickEvent(ClickEvent clickEvent) {
        tvReceive.append("收到一条消息\n");
    }

###数字越大优先级越高
设置优先级以后的效果:
eventbus3.0

可以看到(有一点模糊T.T)是ReceiveEventActivity先接受到事件,MainActivity后收到事件。

以上就是eventbus的简单实用了。

###进阶:
上面的方式都是通过反射的方式获取订阅方法,我们也可以实用annotationProcessor (注释处理工具)来处理,这样的的效率高一点。

然后在app的gradle下面添加:

    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [eventBusIndex: 'study.com.interpolatortestdemo.EventBusIndex']
            }
        }
    }

dependencies {
     implementation 'org.greenrobot:eventbus:3.1.1'
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.0.1'
}

我的整个build文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "study.com.interpolatortestdemo"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        javaCompileOptions{
            annotationProcessorOptions {
                arguments = [ eventBusIndex : 'com.example.EventBusIndex' ]//这个是EventBusIndex的路径
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'org.greenrobot:eventbus:3.1.1'
    annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.1'
}

这里要特别特别特别注意一件事:如果我们要引入索引,我们的项目里必须必须要有EventBus的@Subscribe注解,如果没有的话Eventbus的解释器是不会生成EventBus的索引文件的!

如图,如果我把@Subscribe注释掉的话,是不会产生EventBusIndex的
EventBusIndex
但我打开注释以后就会生成啦
EventBusIndex
我们的项目里使用过EventBus的注解@Subscribe以后,然后rebuild
然后在App类中:

public class App extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        //将MyEventBusIndex安装到默认的eventbus对象里
          EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
    }
}

然后就可以和正常的eventbus一样实用啦:
修改后的MainActivity :

public class MainActivity extends AppCompatActivity {

    private Button btnSend;
    private TextView tvReceive;

    private EventBus eventBus;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //使用订阅者索引方式比反射方式的效率高,这里获取的默认eventbus已经安装了我们的MyEventBusIndex对象了
        eventBus = EventBus.getDefault();
        eventBus.register(this);
//        EventBus.getDefault().register(this);

        btnSend = (Button) findViewById(R.id.btn_send);
        tvReceive = (TextView) findViewById(R.id.tv_receive);

        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               eventBus.post(new ClickEvent());
            }
        });
    }

    @Subscribe(priority = 1)
    public void onReceiveClickEvent(ClickEvent clickEvent) {
        tvReceive.append("收到一条消息\n");
        Log.i("LHD", "MainActivity收到事件");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
//        EventBus.getDefault().unregister(this);
        eventBus.unregister(this);
    }

}

另外EventBus还可以发送黏性事件,即发送事件之后再订阅该事件也能收到该事件,和黏性广播类似。
我们只需要在发送事件的时候使用eventBus.postSticky()方法,在订阅事件的时候增加sticky - true 即可,如:@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
然后注册EventBus以后就能收到该事件啦,这里就不在演示啦,大家可以下载代码以后自己做实验哦。

下一篇将分析EventBus3.0的实现原理。

代码下载:
下载后先rebulid一下生成MyEventBusIndex再运行哦

eventbus3.0 demo-CSDN下载
http://download.csdn.net/download/baidu_31093133/10141993

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值