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事件总线的使用很简单,很好的解决了类与类之间关系过于紧密的问题,进行了很好的解耦操作。