Otto是一个在Android中的事件总线框架,它是square公司的一个开源框架。
为什么要使用Otto事件总线:
通常来说在Android中:
1、Activity与Activity间的传值是通过Intent,值回调是通过startActivityForResult()
2、Activity与Fragment间的传值是通过setArguments,值回调是通过实现onAttach()的Interface方式
3、而Fragment与Fragment间的交互则应该是通过它们关联的Activity作为中间键来交互
4、包括Activity与Service的交互,可能众多同学会采用Binder机制来处理,而其实Binder机制本质也是通过接口回调方式来进行值回调的
5、在更复杂的应用场景下,比如:Activity A跳转到Activity B,Activity B 跳转到Activity C,此时需要从Activity C中获取到用户的操作数据返回到Activity A 和ActivityB中显示,或者在Activity中有多个Fragment,其中一个Fragment里的数据变化需要同步更新其他Fragment的数据变化,这时候如果使用Interface的方式进行它们间的交互则比较复杂,耦合度也高。
所以,针对上面这些问题,大多数在处理值交互的问题上类之间都是耦合在一起的,而Otto事件总线框架就是降低各个类间的耦合度的。
Otto中真正用到的就只有一个类两个注解三个方法:
1、Bus-管理注册、注销和发布事件
2、@Produce-标记该方法是生产者,产生的事件内容为该方法的返回值
3、@Subscribe-标记该方法是订阅者,表示订阅了一个事件,方法需要修饰符为public,而区分不同的订阅者是通过方法的参数来区分的,且订阅了某事件的所有订阅者都可以收到该事件。
4、register(Object obj)-注册,订阅事件前都需要注册
5、unregister(Object obj)-注销,放弃之前所有事件的订阅
6、post(Object event)-发布一个事件,这个事件会被所有标记了@Subscribe注解的方法获得
首先添加依赖
dependencies{ compile 'com.squareup:otto:+' }发布事件有两种方法:
1.使用@Produce注解来产生事件,不过它生产事件前需要注册、生产完事件后需要注销,如果使用这种方法则在跳转到生产者所在的类中则会立即产生事件触发订阅者,即在MainActivity跳转到TestActivity时,会立即产生事件并订阅了该事件的方法会收到该事件,如:
public class TestActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); BusProvider.getInstance().register(this); } @Produce public EventData produceEvent(){ EventData mEventData=new EventData(); mEventData.setContent("hello world!"); return mEventData; } @Override protected void onDestroy(){ super.onDestroy(); BusProvider.getInstance().unregister(this); } public static void jumpToTestActivity(Context context){ context.startActivity(new Intent(context,TestActivity.class)); } }则在MainActivity跳转到TestActivity时订阅者会马上收到事件,输出的Log信息为:
09-06 03:46:16.738 5958-5958/? V/zxy﹕ hello word!
2、通过post()来发布事件,它不需要注册和注销,而且它不会在界面跳转时马上发布事件,而是我们人为的控制该事件什么时候发布,使用如下
public class TestActivity extends AppCpmpatActivity{ @Override protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); } public void click(View view){ EventData mEventData=new EventData(); BusProvider.getInstance().post(mEventData);//发布事件 MainActivity.jumpToMainActivity(this); } public static void jumpToTestActivity(Context context){ context.startActivity(new Intent(context,TestActivity.class)); } }当我们点击按钮的时候,这个事件就发布出去了,而订阅了该事件的方法就会收到,打印的Log为:
09-06 03:46:18.738 5958-5958/? V/zxy﹕ hello word!