Otto是一个事件总线,旨在使您的应用程序的不同部分脱钩,同时仍然允许他们有效沟通。奥托为已经精炼的事件总线增添了独特的功能,并将其专门用于Android平台。
其实Otto-bus 就是观察者模式,它是通过注解的方式来实现过不同模块之间数据的传递,以减少类与类之间的耦合。是一个简单好用的第三方开源工具:
源码地址:http://square.github.io/otto/
Github地址:https://github.com/square/otto
好了废话不多说直接上Demo,很简单。
第一步:为了防止频繁的创建Bus,我将其封装成一个单例,使用静态内部类来做:
package com.lixby.otto;
import com.squareup.otto.Bus;
import com.squareup.otto.ThreadEnforcer;
/**
* Created by Lixby on 2017/7/18.
*/
public class OttoHelper {
private static OttoHelper busHelper;
private Bus bus;
public static OttoHelper getInstance(){
return OttoHelperHolder.busHelper;
}
private static class OttoHelperHolder{
private static final OttoHelper busHelper=new OttoHelper();
}
private OttoHelper(){
//ThreadEnforcer.ANY 在任何线程都可使用
bus=new Bus(ThreadEnforcer.ANY);
}
public void register(Object object){
bus.register(object);
}
public void unregister(Object object){
bus.unregister(object);
}
public void post(Object object){
bus.post(object);
}
}
我用的是Bus bus=new Bus(ThreadEnforcer.ANY)来初始化BusThreadEnforcer.ANY 表示可以在任何线程中进行交互,当然如果你想要在 主线程中交互就可以这么写:Bus bus=new Bus(ThreadEnforcer.MAIN),在子线程去交互就会报异。bus.register(object)订阅, bus.unregister(object)解除订阅,bus.post(object) 事件派发。
第二步:创建Person 类 用于Bus总线事件的订阅传递:
/**
* Created by lixby on 2017/7/18.
*/
public class Person {
private String name;
private String telephone;
public Person(){
}
public Person(String name,String telephone){
this.name=name;
this.telephone=telephone;
}
public String getName() {
return name;
}
public String getTelephone() {
return telephone;
}
public void setName(String name) {
this.name = name;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
}
第三步:订阅和数据处理,先看代码:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.lixby.mode.Person;
import com.lixby.otto.OttoHelper;
import com.squareup.otto.Subscribe;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OttoHelper.getInstance().register(this);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OttoHelper.getInstance().post(new Person("小明","123456789"));
}
});
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,MainActivity2.class));
}
});
}
@Subscribe
public void CallIntoAnyOne(Person person){
Log.i("lixby","Perspn.Name="+person.getName());
}
@Override
protected void onDestroy() {
OttoHelper.getInstance().unregister(this);
super.onDestroy();
}
}
通过OttoHelper.getInstance().register(this)来给MainActivity来订阅注册Bus事件,OttoHelper.getInstance().unregister(this)解除事件,通过注解@Subscribe 来注解一个方法函数,@Subscribe注解的函数名可以随便写,它将会受到订阅的数据,但是参数必须是你要订阅接收的数据,如Person。点击事件触发OttoHelper.getInstance().post(new Person(“小明”,”123456789”)),看下log日志,这算是一个简单的事件总线的流程:
第四步:创建MainActivity2 ,MainActivity跳转到它,并在M2中添加Bus事件:
package come.lixby.ottotest;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.lixby.mode.Person;
import com.lixby.otto.OttoHelper;
import com.squareup.otto.Produce;
import com.squareup.otto.Subscribe;
public class MainActivity2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OttoHelper.getInstance().register(this);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
OttoHelper.getInstance().post(new Person("小红","789456123"));
}
});
}
@Produce
public Person producePerson(){
return new Person("小狗","258369741");
}
@Subscribe
public void callIntoXiaoHong(Person person){
Log.d("lixby","Perspn.Name="+person.getName());
}
@Override
protected void onDestroy() {
OttoHelper.getInstance().unregister(this);
super.onDestroy();
}
}
M2代码逻辑和M1基本一样,修改传递数据,然后触发:
看到没M1的是绿色,M2的是灰色,M1的订阅也被触发了,这是因为在从M1跳转到M2的时候没有M1并没有取消Bus是讲的订阅,只要有其他模块
发送相同订阅的数据时,也会收到数据。然后退出M2 ,在M2的onDestroy中取消订阅。在M1中再出发事件M2就收不到了,为什么,大家应该
都明白。
最后我们来看下@Produce这个注解,用法很简单,通过它标识的方法函数在不调用Bus的post方法时会主动调用并将结果传递给@Subscribe标
识的方法函数,但是要注意@Produce表示的方法函数必须返回实例对象或这个null,如果是null,@Subscribe表示的函数是不会被触发,也
就是不会收到任何数据。
最后来看下测试结果,我在M2用到了@Produce ,在从M1跳转到M2 没有触发M2的OnClick事件,producePerson()函数被主动触发了。
Over!