引用知乎:
最近在想安卓这边应该如何更好地分发代码,以前一直用广播,但是一般认为本地广播是三种方式中消耗时间、空间最多的一种方式,但也是同 android 相性最好的方式。因为广播属于 android 四大组件之一,在 BroadcastReceiver 中的 onReceive 方法中可以获得 Context、Intent 参数。持有这两个参数便可以调用许多 android sdk 中的方法,这一优势另外两种方式很难弥补的,无论是 EventBus 还是观察者,需要获得 Context 的话,往往都需要进行复杂的参数传递或者是依赖注入。
本地广播另外的一个优点是,许多系统级的事件都是使用广播来进行通知的,像常用的电量变化、网络状态变化、短信发送接收的状态等等。这就使得与 android 系统相关的通知,广播往往成了唯一的选择。但这并不意味着 android 系统中的通知都应该使用广播,因为相对于其它的方式而言,广播是重量级的、消耗资源较多的方式。广播的优势体现在它与 android sdk 链接的更紧密,当我们需要同 android 交互的时候,广播提供的便捷性抵消掉了它过多的资源消耗。但是对于不需要同 android 交互或是只做很少的交互的时候,使用广播往往是一种浪费。
所以在不需要系统调用、进程通信的时候就可以不用广播,但是因为EventBus是基于反射的,利用方法名,来定义事件的,这会导致该类无法混淆,所以在一般情况下,使用观察者就可以达通知的目的。
根据网上的一个观察者模式:
但是把所有的观察者放在一个队列里,如果有一个事件需要通知,就需要遍历所有观察者,这感觉不太好,所以我按照EventBus的思路,改为map存储,使用事件对应订阅者列表,但是就无法通过继承父类来订阅和取消订阅,这大概就是有得有失吧。
修改的部分如下:
package com.example.jaydon.observable;
import android.text.TextUtils ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.concurrent.CopyOnWriteArrayList ;
/**
* 具体的主题角色的实现,这里用来监听事件的发生,采用单例模式来实现
* Created by Jaydon on 2015/12/20.
*/
public class EventSubject implements EventSubjectInterface{
// private List<EventObserver> mEventObservers = new ArrayList<EventObserver>();
private static final Map<String, CopyOnWriteArrayList<EventObserver>> mEventObservers = new HashMap<String, CopyOnWriteArrayList<EventObserver>>() ; //每个事件的父类、接口
private static volatile EventSubject mEventSubject;
private EventSubject(){
}
public static EventSubject getInstance(){
if (null == mEventSubject){
synchronized (EventSubject.class) {
if( null == mEventSubject) {
mEventSubject = new EventSubject();
}
}
}
return mEventSubject;
}
@Override
public void registerObserver(EventObserver observer, String eventType) throws Exception {
if (TextUtils.isEmpty(eventType) || null == observer) {
throw new Exception("参数不正确");
}
synchronized (mEventObservers){
CopyOnWriteArrayList<EventObserver> observers = mEventObservers .get(eventType);
if( null == observers) {
observers = new CopyOnWriteArrayList<>() ;
mEventObservers.put(eventType , observers);
}
if (observers.contains(observer)){
throw new Exception( "已经注册过" );
}
observers.add(observer);
}
}
@Override
public void removeObserver(EventObserver observer, String eventType) throws Exception {
if (TextUtils.isEmpty(eventType) || null == observer) {
throw new Exception("参数不正确");
}
synchronized (mEventObservers){
CopyOnWriteArrayList<EventObserver> observers = mEventObservers .get(eventType);
if( null == observers) {
throw new Exception( "未注册过" );
}
int index = observers.indexOf(observer) ;
if (index >= 0) {
mEventObservers.remove(observer) ;
}
}
}
@Override
public void notifyObserver(String eventType) throws Exception {
if (TextUtils.isEmpty(eventType)) {
throw new Exception("参数不正确");
}
CopyOnWriteArrayList<EventObserver> observers = mEventObservers .get(eventType);
if( null == observers) {
throw new Exception("未注册过");
}
if (mEventObservers!= null && mEventObservers.size()> 0){
for (EventObserver observer : observers){
observer.dispatchChange(eventType) ;
}
}
}
import android.text.TextUtils ;
import java.util.HashMap ;
import java.util.Map ;
import java.util.concurrent.CopyOnWriteArrayList ;
/**
* 具体的主题角色的实现,这里用来监听事件的发生,采用单例模式来实现
* Created by Jaydon on 2015/12/20.
*/
public class EventSubject implements EventSubjectInterface{
// private List<EventObserver> mEventObservers = new ArrayList<EventObserver>();
private static final Map<String, CopyOnWriteArrayList<EventObserver>> mEventObservers = new HashMap<String, CopyOnWriteArrayList<EventObserver>>() ; //每个事件的父类、接口
private static volatile EventSubject mEventSubject;
private EventSubject(){
}
public static EventSubject getInstance(){
if (null == mEventSubject){
synchronized (EventSubject.class) {
if( null == mEventSubject) {
mEventSubject = new EventSubject();
}
}
}
return mEventSubject;
}
@Override
public void registerObserver(EventObserver observer, String eventType) throws Exception {
if (TextUtils.isEmpty(eventType) || null == observer) {
throw new Exception("参数不正确");
}
synchronized (mEventObservers){
CopyOnWriteArrayList<EventObserver> observers = mEventObservers .get(eventType);
if( null == observers) {
observers = new CopyOnWriteArrayList<>() ;
mEventObservers.put(eventType , observers);
}
if (observers.contains(observer)){
throw new Exception( "已经注册过" );
}
observers.add(observer);
}
}
@Override
public void removeObserver(EventObserver observer, String eventType) throws Exception {
if (TextUtils.isEmpty(eventType) || null == observer) {
throw new Exception("参数不正确");
}
synchronized (mEventObservers){
CopyOnWriteArrayList<EventObserver> observers = mEventObservers .get(eventType);
if( null == observers) {
throw new Exception( "未注册过" );
}
int index = observers.indexOf(observer) ;
if (index >= 0) {
mEventObservers.remove(observer) ;
}
}
}
@Override
public void notifyObserver(String eventType) throws Exception {
if (TextUtils.isEmpty(eventType)) {
throw new Exception("参数不正确");
}
CopyOnWriteArrayList<EventObserver> observers = mEventObservers .get(eventType);
if( null == observers) {
throw new Exception("未注册过");
}
if (mEventObservers!= null && mEventObservers.size()> 0){
for (EventObserver observer : observers){
observer.dispatchChange(eventType) ;
}
}
}
}
如此使用:
package
com.example.jaydon.activity
;
import android.os.Bundle ;
import android.support.design.widget.FloatingActionButton ;
import android.support.design.widget.Snackbar ;
import android.support.v7.widget.Toolbar ;
import android.view.View ;
import com.example.jaydon.R ;
import com.example.jaydon.observable.EventObserver ;
import com.example.jaydon.observable.EventSubject ;
import com.example.jaydon.observable.EventType ;
import com.example.jaydon.observable.Notify ;
public class MainActivity extends BaseActivity {
private ActivityEventObserver mActivityEventObserver ;
@Override
protected void onCreate (Bundle savedInstanceState) {
super .onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main ) ;
mActivityEventObserver = new ActivityEventObserver( this ) ;
registerObserver( mActivityEventObserver ) ;
initView() ;
}
private void initView () {
Toolbar toolbar = (Toolbar) findViewById(R.id. toolbar ) ;
setSupportActionBar(toolbar) ;
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id. fab ) ;
fab.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick (View view) {
Snackbar.make(view , "Replace with your own action" , Snackbar. LENGTH_LONG )
.setAction( "Action" , null ).show() ;
Notify.getInstance().NotifyActivity(EventType.UPDATE_TEXT ) ;
Notify.getInstance().NotifyActivity(EventType. UPDATE_MAIN ) ;
}
}) ;
}
@Override
protected void onDestroy () {
super .onDestroy() ;
removeObserver( mActivityEventObserver ) ;
}
public void registerObserver (EventObserver observer) {
final String[] observerEventTypes = getObserverEventType() ; //获取所有需要监听的业务类型
final EventSubject eventSubject = EventSubject. getInstance() ;
if ( null != observerEventTypes && observerEventTypes. length > 0 ){
for (String eventType : observerEventTypes) {
try {
eventSubject.registerObserver(observer , eventType) ;
} catch (Exception e) {
e.printStackTrace() ;
}
}
}
}
public void removeObserver (EventObserver observer) {
final String[] observerEventTypes = getObserverEventType() ; //获取所有需要监听的业务类型
final EventSubject eventSubject = EventSubject. getInstance() ;
if ( null != observerEventTypes && observerEventTypes. length > 0 ){
for (String eventType : observerEventTypes) {
try {
eventSubject.removeObserver(observer , eventType) ;
} catch (Exception e) {
e.printStackTrace() ;
}
}
}
}
@Override
protected void onChange (String eventType) {
if (EventType. UPDATE_MAIN ==eventType){
showShortToast(EventType. UPDATE_MAIN ) ;
} else if (EventType.UPDATE_TEXT ==eventType){
showShortToast(EventType.UPDATE_TEXT ) ;
}
}
@Override
protected String[] getObserverEventType () {
return new String[]{
EventType. UPDATE_MAIN ,
EventType.UPDATE_TEXT
} ;
}
import android.os.Bundle ;
import android.support.design.widget.FloatingActionButton ;
import android.support.design.widget.Snackbar ;
import android.support.v7.widget.Toolbar ;
import android.view.View ;
import com.example.jaydon.R ;
import com.example.jaydon.observable.EventObserver ;
import com.example.jaydon.observable.EventSubject ;
import com.example.jaydon.observable.EventType ;
import com.example.jaydon.observable.Notify ;
public class MainActivity extends BaseActivity {
private ActivityEventObserver mActivityEventObserver ;
@Override
protected void onCreate (Bundle savedInstanceState) {
super .onCreate(savedInstanceState) ;
setContentView(R.layout. activity_main ) ;
mActivityEventObserver = new ActivityEventObserver( this ) ;
registerObserver( mActivityEventObserver ) ;
initView() ;
}
private void initView () {
Toolbar toolbar = (Toolbar) findViewById(R.id. toolbar ) ;
setSupportActionBar(toolbar) ;
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id. fab ) ;
fab.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick (View view) {
Snackbar.make(view , "Replace with your own action" , Snackbar. LENGTH_LONG )
.setAction( "Action" , null ).show() ;
Notify.getInstance().NotifyActivity(EventType.UPDATE_TEXT ) ;
Notify.getInstance().NotifyActivity(EventType. UPDATE_MAIN ) ;
}
}) ;
}
@Override
protected void onDestroy () {
super .onDestroy() ;
removeObserver( mActivityEventObserver ) ;
}
public void registerObserver (EventObserver observer) {
final String[] observerEventTypes = getObserverEventType() ; //获取所有需要监听的业务类型
final EventSubject eventSubject = EventSubject. getInstance() ;
if ( null != observerEventTypes && observerEventTypes. length > 0 ){
for (String eventType : observerEventTypes) {
try {
eventSubject.registerObserver(observer , eventType) ;
} catch (Exception e) {
e.printStackTrace() ;
}
}
}
}
public void removeObserver (EventObserver observer) {
final String[] observerEventTypes = getObserverEventType() ; //获取所有需要监听的业务类型
final EventSubject eventSubject = EventSubject. getInstance() ;
if ( null != observerEventTypes && observerEventTypes. length > 0 ){
for (String eventType : observerEventTypes) {
try {
eventSubject.removeObserver(observer , eventType) ;
} catch (Exception e) {
e.printStackTrace() ;
}
}
}
}
@Override
protected void onChange (String eventType) {
if (EventType. UPDATE_MAIN ==eventType){
showShortToast(EventType. UPDATE_MAIN ) ;
} else if (EventType.UPDATE_TEXT ==eventType){
showShortToast(EventType.UPDATE_TEXT ) ;
}
}
@Override
protected String[] getObserverEventType () {
return new String[]{
EventType. UPDATE_MAIN ,
EventType.UPDATE_TEXT
} ;
}
}