引用知乎:
最近在想安卓这边应该如何更好地分发代码,以前一直用广播,但是一般认为本地广播是三种方式中消耗时间、空间最多的一种方式,但也是同 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<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
}
;
}
}