Otto是Square提供的一个Android事件总线框架
一、使用Otto事件总线框架的原因
1.一般情况下,在Android中的Activity与Activity之间值的传递,我们通过Intent的方式;
2.Activity与Fragment之间我们通过setArguments,值回调我们是在Fragment中的onAttach()接口方式实现;
3.Activity与service之间,我们通常会使用binder机制,但是binder机制实际上使用的也是接口回调的方式;
4.在一些比较复杂的情况,比如Activity嵌套多个Fragment页面的时候,如果一个页面的值发生了改变,其他的页面也要跟着发生数据的更新操作,这样我们会频繁的使用接口回调的方式,这种方式的耦合性太高。
针对以上出现的问题,我们在这里引入了Otto事件总线的方式,处理耦合性比较高的一些问题。
二、Otto事件总线
1.Otto事件总线使用到的有:一个类Bus,两个注解@Produce和@Subscribe,三个方法register(Object obj)注册事件的方法,一般我们在初始化的时候要将Otto事件进行注册,unregister(Object obj)取消订阅的方法,我们可以再Activity中的OnDestroy()方法中调用该方法取消注册。
2.Otto事件总线的使用方法(这里以Eclipse进行讲解,Android Studio详见官方项目文档)
(1)下载最新的Otto的jar包,导入我们的主工程
(2)为了频繁的创建Bus类的对象,我们这里创建一个单利的类解决这个问题,并在onCreate()方法里面调用BusProvider.getInstance().register(this);进行注册;在onDestroy()方法里面调用BusProvider.getInstance().unregister(this);取消订阅事件总线
<span style="font-size:14px;">package com.example.ottodemo;
import com.squareup.otto.Bus;
public class BusProvider {
private volatile static Bus bus=null; //使用volatile来修饰多线程访问变量的情况
private BusProvider(){
}
public static Bus getInstance(){
if(bus==null){
synchronized (BusProvider.class) { //加上sunchronized来防止并发
bus=new Bus();
}
}
return bus;
}
}
</span>
(3)创建一个Bean类来保存我们的数据,比如保存一个字符串String:"你好"
package com.example.ottodemo.bean;
public class EventData {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
(4)订阅了我们事件的方法就可以接收我们的数据,我们使用@Subscribe在方法上面来进行订阅,如下代码所示:
<span style="color:#FF0000;">@Subscribe</span>
public void subscribeEvent(EventData data){
Toast.makeText(this, data.getContent(), Toast.LENGTH_SHORT).show();
}
(5)发布事件有两种方式
第一种:
我们可以在方法的上面通过注解@Produce进行事件的发布,注意:这个方法发布事件的时候,方法返回不能为空,否则会报错
package com.example.ottodemo;
import com.example.ottodemo.bean.EventData;
import com.squareup.otto.Produce;
import com.squareup.otto.Subscribe;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BusProvider.getInstance().register(this); //注册事件
mButton = (Button) findViewById(R.id.btn);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
TestActivity.jumpToTestActivity(MainActivity.this);
}
});
}
@Produce
public EventData providerEvent(){
EventData eventData = new EventData();
eventData.setContent("hello world");
return eventData;
}
/*@Subscribe
public void subscribeEvent(EventData data){
Toast.makeText(this, data.getContent()+"1", Toast.LENGTH_SHORT).show();
}*/
@Override
protected void onDestroy() {
super.onDestroy();
BusProvider.getInstance().unregister(this); //取消订阅
}
public static void jumpToMainActivity(Context context){
context.startActivity(new Intent(context,MainActivity.class));
}
}
第二种:
我们通过提供的方法post()进行发布,使用这种方式我们可以进行控制什么时候发布事件,通知其他页面接收数据进行操作。而使用@produce注解的方法,只要页面订阅了事件就会立即接收数据进行操作。
package com.example.ottodemo;
import com.example.ottodemo.bean.EventData;
import com.squareup.otto.Subscribe;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class TestActivity extends Activity {
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
BusProvider.getInstance().register(this); //订阅事件
mButton = (Button) findViewById(R.id.btn_test);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EventData eventData = new EventData();
eventData.setContent("hello world");
BusProvider.getInstance().post(eventData);
}
});
}
@Subscribe
public void subscribeEvent(EventData data){
Toast.makeText(this, data.getContent(), Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
BusProvider.getInstance().unregister(this); //取消订阅
}
public static void jumpToTestActivity(Context context){
context.startActivity(new Intent(context,TestActivity.class));
}
}
通过以上的实例可以看出Otto事件总线的使用很简单,很好的解决了类与类之间关系过于紧密的问题,进行了很好的解耦操作。