Android 广播、EventBus、观察者模式

引用知乎:
最近在想安卓这边应该如何更好地分发代码,以前一直用广播,但是一般认为本地广播是三种方式中消耗时间、空间最多的一种方式,但也是同 android 相性最好的方式。因为广播属于 android 四大组件之一,在 BroadcastReceiver 中的 onReceive 方法中可以获得 Context、Intent 参数。持有这两个参数便可以调用许多 android sdk 中的方法,这一优势另外两种方式很难弥补的,无论是 EventBus 还是观察者,需要获得 Context 的话,往往都需要进行复杂的参数传递或者是依赖注入。
本地广播另外的一个优点是,许多系统级的事件都是使用广播来进行通知的,像常用的电量变化、网络状态变化、短信发送接收的状态等等。这就使得与 android 系统相关的通知,广播往往成了唯一的选择。但这并不意味着 android 系统中的通知都应该使用广播,因为相对于其它的方式而言,广播是重量级的、消耗资源较多的方式。广播的优势体现在它与 android sdk 链接的更紧密,当我们需要同 android 交互的时候,广播提供的便捷性抵消掉了它过多的资源消耗。但是对于不需要同 android 交互或是只做很少的交互的时候,使用广播往往是一种浪费
所以在不需要系统调用、进程通信的时候就可以不用广播,但是因为EventBus是基于反射的,利用方法名,来定义事件的,这会导致该类无法混淆,所以在一般情况下,使用观察者就可以达通知的目的。
根据网上的一个观察者模式:
http://www.akiyamayzw.com/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E5%9C%A8android-%E4%B8%8A%E7%9A%84%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/
但是把所有的观察者放在一个队列里,如果有一个事件需要通知,就需要遍历所有观察者,这感觉不太好,所以我按照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 mEventObservers = new ArrayList();
   
private static final Map, CopyOnWriteArrayList> mEventObservers = new HashMap, CopyOnWriteArrayList>() ; //每个事件的父类、接口
   
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 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 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 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
        }
;
   
}

}

你可能感兴趣的:(安卓)