您的位置:首页 > 移动开发 > Android开发

观察者模式的扩展--随记

2016-01-29 14:21 381 查看
背景,最近项目用的是socket通信,socket会不断的更新后台数据,而这时,一个界面得观察好几个数据的变化,而这几个数据都是同类型,导致界面接受的一方,无法区分。
java自带的Observable中的Observer是一个list,这样导致只能把object通知到Observer中去,而不能以何种方式通知过去。还有我用的是socket通信,是在thread中刷数据的,要更新UI必须还得一个handler来处理。这样导致java中的观察者不太实用了。
如果把list拓展成map呢。。。
Observable类实现如下:


public class Observable {
HashMap<Integer, ArrayList<Observer>> obserMap = new HashMap<Integer, ArrayList<Observer>>();
public void registObserver(int key,Observer obser){
ArrayList<Observer> obsers = obserMap.get(key);
if (obsers == null) {
obsers = new ArrayList<Observer>();
obsers.add(obser);
obserMap.put(key, obsers);
}
if (obsers.contains(obser)) {
return;
} else {
obsers.add(obser);
}

}
public void notifyDataChanged(int key,Object object){
ArrayList<Observer> obsers = obserMap.get(key);
if (obsers == null) {
Log.e("", "obsers is null");
return;
} else {
Message message = Message.obtain();
GlobleHandle a = AppContext.getInstance().globleHandle;
for(Observer o:obsers) {
BeenObser beanObser = new BeenObser(object, key,o);
message.obj = beanObser;
a.sendMessage(message);
}
}
}
public void unRegestObser(int key,Observer obser) {
ArrayList<Observer> obsers = obserMap.get(key);
if (obsers == null) {
return;
} else {
if(obsers.contains(obser)) {
obsers.remove(obser);
}
}
}
public void unRegestObser(Observer obser) {

}
}


主要思想呢,通过notifyDataChanged,把map中的key值与observer包装成一个BeenObser对象,handler,消息发送出去。
observer接口一样


public interface Observer {
void update(int key,Object o);
}


handler发送消息:

handler要在程序启动初始化一下,我的是在AppContext中初始化的。

public class GlobleHandle extends Handler{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if (msg.obj instanceof BeenObser) {
BeenObser beenObser = (BeenObser) msg.obj;
beenObser.getObser().update(beenObser.getKey(), beenObser.getO());
}
}
}


BeenObserver包装类:

public class BeenObser {
private Object o;
private int key;
private Observer obser;
public BeenObser(Object o, int key, Observer obser) {
super();
this.o = o;
this.key = key;
this.obser = obser;
}
public Object getO() {
return o;
}
public void setO(Object o) {
this.o = o;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public Observer getObser() {
return obser;
}
public void setObser(Observer obser) {
this.obser = obser;
}

}


使用情况如下:
在控制层extend Obserable,在view中注册 实现observer接口,update就可以了。


public class HtmlFragment extends Fragment implements Observer {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {        ProcessCenter.instance().dataHandlService.registObserver(
Constant.SET_WRITER, this);     ProcessCenter.instance().dataHandlService.registObserver(
Constant.OPEN_KEYBOARD, this);      ProcessCenter.instance().dataHandlService.registObserver(
Constant.FEED_BACK_MSG, this);      ProcessCenter.instance().dataHandlService.registObserver(
Constant.LOAD_WEB
4000
_URL, this);
return view;
}

@Override
public void onDestroy() {
super.onDestroy();      ProcessCenter.instance().dataHandlService.unRegestObser(
Constant.SET_WRITER, this);
ProcessCenter.instance().dataHandlService.unRegestObser(
Constant.LOAD_WEB_URL, this);
ProcessCenter.instance().dataHandlService.unRegestObser(
Constant.FEED_BACK_MSG, this);
ProcessCenter.instance().dataHandlService.unRegestObser(
Constant.OPEN_KEYBOARD, this);
}
@Override
public void update(int key, Object o) {
number = "";
if (mKeyboard != null) {
mKeyboard.closeKeyboard();
}
switch (key) {
case Constant.LOAD_WEB_URL:
String fileName = ((String) o).replaceAll(".zip", "");
break;
case Constant.FEED_BACK_MSG:
int timeout = (Integer) o;
break;
case Constant.OPEN_KEYBOARD:
boolean isOpen = (Boolean) o;

break;
default:
break;
}
}
}


上面dataHandlService这个继承observer就可以了,这个使用起来非常方便,大大降低view之间的耦合性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 观察者 扩展