引用知乎:
最近在想安卓这边应该如何更好地分发代码,以前一直用广播,但是一般认为本地广播是三种方式中消耗时间、空间最多的一种方式,但也是同 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存储,使用事件对应订阅者列表,但是就无法通过继承父类来订阅和取消订阅,这大概就是有得有失吧。
修改的部分如下:
packagecom.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 classEventSubjectimplementsEventSubjectInterface{
// private List<EventObserver> mEventObservers = new ArrayList<EventObserver>();
private static finalMap<String,CopyOnWriteArrayList<EventObserver>>mEventObservers=newHashMap<String,CopyOnWriteArrayList<EventObserver>>();//每个事件的父类、接口
private static volatileEventSubjectmEventSubject;
private EventSubject(){
}
public staticEventSubjectgetInstance(){
if(null==mEventSubject){
synchronized(EventSubject.class) {
if(null==mEventSubject) {
mEventSubject=newEventSubject();
}
}
}
returnmEventSubject;
}
@Override
public voidregisterObserver(EventObserver observer,String eventType)throwsException {
if(TextUtils.isEmpty(eventType) ||null== observer) {
throw newException("参数不正确");
}
synchronized(mEventObservers){
CopyOnWriteArrayList<EventObserver> observers = mEventObservers.get(eventType);
if(null== observers) {
observers = new CopyOnWriteArrayList<>();
mEventObservers.put(eventType,observers);
}
if(observers.contains(observer)){
throw newException("已经注册过");
}
observers.add(observer);
}
}
@Override
public voidremoveObserver(EventObserver observer,String eventType)throwsException {
if(TextUtils.isEmpty(eventType) ||null== observer) {
throw newException("参数不正确");
}
synchronized(mEventObservers){
CopyOnWriteArrayList<EventObserver> observers = mEventObservers.get(eventType);
if(null== observers) {
throw newException("未注册过");
}
intindex = observers.indexOf(observer);
if (index >=0) {
mEventObservers.remove(observer);
}
}
}
@Override
public voidnotifyObserver(String eventType)throwsException {
if(TextUtils.isEmpty(eventType)) {
throw newException("参数不正确");
}
CopyOnWriteArrayList<EventObserver> observers = mEventObservers.get(eventType);
if(null== observers) {
throw newException("未注册过");
}
if(mEventObservers!=null&&mEventObservers.size()>0){
for(EventObserver observer : observers){
observer.dispatchChange(eventType) ;
}
}
}
}
如此使用:
packagecom.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 MainActivityextendsBaseActivity {
privateActivityEventObservermActivityEventObserver;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActivityEventObserver=newActivityEventObserver(this);
registerObserver(mActivityEventObserver);
initView();
}
private voidinitView() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(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 voidonDestroy() {
super.onDestroy();
removeObserver(mActivityEventObserver);
}
public voidregisterObserver(EventObserver observer) {
finalString[] observerEventTypes = getObserverEventType();//获取所有需要监听的业务类型
finalEventSubject eventSubject = EventSubject.getInstance();
if(null!= observerEventTypes && observerEventTypes.length>0){
for(String eventType : observerEventTypes) {
try{
eventSubject.registerObserver(observer , eventType);
}catch(Exception e) {
e.printStackTrace() ;
}
}
}
}
public voidremoveObserver(EventObserver observer) {
finalString[] observerEventTypes = getObserverEventType();//获取所有需要监听的业务类型
finalEventSubject 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 voidonChange(String eventType) {
if(EventType.UPDATE_MAIN==eventType){
showShortToast(EventType.UPDATE_MAIN);
}else if(EventType.UPDATE_TEXT==eventType){
showShortToast(EventType.UPDATE_TEXT);
}
}
@Override
protectedString[]getObserverEventType() {
return newString[]{
EventType.UPDATE_MAIN,
EventType.UPDATE_TEXT
};
}
}
相关文章
- Android(java)学习笔记179:BroadcastReceiver之 有序广播和无序广播(BroadcastReceiver优先级)
- Android广播最佳实践
- android广播注册简单用法
- Android学习总结——本地广播机制
- 【Android】Android 广播大全
- Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)
- Android中通过广播方式调起第三方App
- 自定义广播(BroadcastReceiver)事件 --Android开发
- Android利用广播监听设备安装和卸载应用程序
- [RK3288][Android6.0] 调试笔记 --- 动态显示和隐藏导航栏(广播方式)