自己写的一个android中关于观察者模式的demo。关于观察者的定义,可以看另外一篇文章:Java设计模式之观察者模式
下面先来看看代码的结构图:
结构的大体说明:包manager和包managerimpl用来管理观察者,包manager中是抽象的观察者,包managerimpl中是具体的观察者。
包listener和包notify 用来管理被观察者(也成为目标),包listener中是抽象的被观察者,提供注册和删除观察者对象的接口,包notify中是具体的被观察者,当它的状态发送改变时,向它的各个观察者发出通知。
包common中的类起全局的作用,用来管理所有的观察者。
与上面的包的路径平行的是包fragment和MainActivity,TestService,TestPrint等类,这些类是实现观察者接口的对象,具体分为4种类型:Activity,Fragment,Service和普通的类(TestPrint.java)。因为Android中入口程序是在Activity中,所以普通类TestPrint.java还要另外提供一个方法addListener()来使自己实现观察着的接口,并且将这个方法放在MainActivity中调用。
代码如下,
包notify中:
//一个最基本的空的interface,用来管理具体的被观察者
....还有其他的具体的被观察者,格式同上面。
包manager中:
包managerimpl中:
//实现了抽象的观察者ManagerOne,并且观察两个目标
//实现了抽象的观察者ManagerTwo,并且观察四个目标
还有一个很重要的包:common
//用来管理所有的观察者
上面就是大体的观察者和被观察者,其次就是实现观察者接口的对象,具体分为4种类型:Activity,Fragment,Service和普通的类(TestPrint.java)。大体的功能已经在上面说过了。因为除了实现观察者外,他们都没有其他的逻辑,所以这里就不列出代码了。下面是模拟接收到消息并通知观察者的SendMsgActivity:
下面是整个demo运行后的效果图:
下面先来看看代码的结构图:
结构的大体说明:包manager和包managerimpl用来管理观察者,包manager中是抽象的观察者,包managerimpl中是具体的观察者。
包listener和包notify 用来管理被观察者(也成为目标),包listener中是抽象的被观察者,提供注册和删除观察者对象的接口,包notify中是具体的被观察者,当它的状态发送改变时,向它的各个观察者发出通知。
包common中的类起全局的作用,用来管理所有的观察者。
与上面的包的路径平行的是包fragment和MainActivity,TestService,TestPrint等类,这些类是实现观察者接口的对象,具体分为4种类型:Activity,Fragment,Service和普通的类(TestPrint.java)。因为Android中入口程序是在Activity中,所以普通类TestPrint.java还要另外提供一个方法addListener()来使自己实现观察着的接口,并且将这个方法放在MainActivity中调用。
代码如下,
包listener中:两个类中共有6个方法,模拟收到了6中不同的消息,然后通知观察者。这里为了简单,通知的内容都是基本数据类型,具体情况中可以使用JavaBean实现。
public interface RecvMsgOne {
public void notifyRecvMsgHaHa(String haha);
public void notifyRecvMsgXiXi(String xixi);
}
public interface RecvMsgTwo {
public void notifyRecvName(String str);
public void notifyRecvAge(int num);
public void notifyRecvSex(boolean bool);
public void notifyRecvAddress(String address);
}
包notify中:
//一个最基本的空的interface,用来管理具体的被观察者
public interface BaseListener {
}
public interface OnRecvMsgHaHa extends BaseListener{
public void onRecvHaHa(String haha);
}
public interface OnRecvMsgXiXi extends BaseListener{
public void onRecvXiXi(String xixi);
}
public interface OnRecvMsgName extends BaseListener{
public void onRecvName(String name);
}
....还有其他的具体的被观察者,格式同上面。
包manager中:
public interface ManagerOne{
public void addListenerOne(RecvMsgOne listener);
public void removeListenerOne(RecvMsgOne listener);
}
public interface ManagerTwo {
public void addListenerTwo(RecvMsgTwo listener);
public void removeListenerTwo(RecvMsgTwo listener);
}
包managerimpl中:
//实现了抽象的观察者ManagerOne,并且观察两个目标
public class ManagerImplOne implements ManagerOne, OnRecvMsgHaHa, OnRecvMsgXiXi{
public ManagerImplOne(){
SendMsgActivity.addListener(this);
}
private List<RecvMsgOne> recvMsgOneList = new CopyOnWriteArrayList<RecvMsgOne>();
@Override
public void addListenerOne(RecvMsgOne listener) {
synchronized (recvMsgOneList) {
if (!recvMsgOneList.contains(listener)) {
recvMsgOneList.add(listener);
}
}
}
@Override
public void removeListenerOne(RecvMsgOne listener) {
synchronized (recvMsgOneList) {
if(recvMsgOneList.contains(listener)){
recvMsgOneList.remove(listener);
}
}
}
@Override
public void onRecvXiXi(String xixi) {
synchronized(recvMsgOneList){
for(RecvMsgOne l : recvMsgOneList){
l.notifyRecvMsgXiXi(xixi);
}
}
}
@Override
public void onRecvHaHa(String haha) {
synchronized(recvMsgOneList){
for(RecvMsgOne l : recvMsgOneList){
l.notifyRecvMsgHaHa(haha);
}
}
}
}
//实现了抽象的观察者ManagerTwo,并且观察四个目标
public class ManagerImplTwo implements ManagerTwo, OnRecvMsgName, OnRecvMsgAge,
OnRecvMsgSex, OnRecvMsgAddress {
public ManagerImplTwo(){
SendMsgActivity.addListener(this);
}
private List<RecvMsgTwo> recvMsgTwoList = new CopyOnWriteArrayList<RecvMsgTwo>();
@Override
public void addListenerTwo(RecvMsgTwo listener) {
synchronized (recvMsgTwoList) {
if (!recvMsgTwoList.contains(listener)) {
recvMsgTwoList.add(listener);
}
}
}
@Override
public void removeListenerTwo(RecvMsgTwo listener) {
synchronized (recvMsgTwoList) {
if (recvMsgTwoList.contains(listener)) {
recvMsgTwoList.remove(listener);
}
}
}
@Override
public void onRecvAddress(String address) {
synchronized (recvMsgTwoList) {
for (RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvAddress(address);
}
}
}
@Override
public void onRecvSex(boolean sex) {
synchronized (recvMsgTwoList) {
for (RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvSex(sex);
}
}
}
@Override
public void onRecvAge(int age) {
synchronized(recvMsgTwoList){
for (RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvAge(age);
}
}
}
@Override
public void onRecvName(String name) {
synchronized(recvMsgTwoList){
for (RecvMsgTwo l : recvMsgTwoList) {
l.notifyRecvName(name);
}
}
}
}
还有一个很重要的包:common
//用来管理所有的观察者
public class GlobalManager {
private static ManagerOne managerOne;
private static ManagerTwo managerTwo;
public static ManagerOne getManagerOne(){
if(null == managerOne){
managerOne = new ManagerImplOne();
}
return managerOne;
}
public static ManagerTwo getManagerTwo(){
if(null == managerTwo){
managerTwo = new ManagerImplTwo();
}
return managerTwo;
}
}
上面就是大体的观察者和被观察者,其次就是实现观察者接口的对象,具体分为4种类型:Activity,Fragment,Service和普通的类(TestPrint.java)。大体的功能已经在上面说过了。因为除了实现观察者外,他们都没有其他的逻辑,所以这里就不列出代码了。下面是模拟接收到消息并通知观察者的SendMsgActivity:
public class SendMsgActivity extends Activity{
private Button btnSend;
private EditText edit;
private String msgType;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("模拟收到消息的界面");
setContentView(R.layout.activity_sendmsg);
btnSend = (Button) findViewById(R.id.sendAct_send);
edit = (EditText) findViewById(R.id.sendAct_edit);
btnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
sendMsg();
}
});
}
protected void sendMsg() {
msgType = edit.getText().toString().trim();
int type = Integer.valueOf(msgType);
switch (type) {
case 1:
for(OnRecvMsgHaHa l : onRecvMsgHaHaList){
l.onRecvHaHa("Hahahaha...");
}
break;
case 2:
for(OnRecvMsgXiXi l : onRecvMsgXiXiList){
l.onRecvXiXi("Xixixixi...");
}
break;
case 3:
for(OnRecvMsgName l : onRecvMsgNameList){
l.onRecvName("XiaoMing");
}
break;
case 4:
for(OnRecvMsgSex l : onRecvMsgSexList){
l.onRecvSex(true);
}
break;
case 5:
for(OnRecvMsgAge l : onRecvMsgAgeList){
l.onRecvAge(24);
}
break;
case 6:
for(OnRecvMsgAddress l : onRecvMsgAddressList){
l.onRecvAddress("杭州市西湖区");
}
break;
default:
break;
}
}
/*** 通过下面的list给所有注册的观察者发送消息 ***/
private static List<OnRecvMsgAddress> onRecvMsgAddressList = new CopyOnWriteArrayList<OnRecvMsgAddress>();
private static List<OnRecvMsgAge> onRecvMsgAgeList = new CopyOnWriteArrayList<OnRecvMsgAge>();
private static List<OnRecvMsgHaHa> onRecvMsgHaHaList = new CopyOnWriteArrayList<OnRecvMsgHaHa>();
private static List<OnRecvMsgXiXi> onRecvMsgXiXiList = new CopyOnWriteArrayList<OnRecvMsgXiXi>();
private static List<OnRecvMsgSex> onRecvMsgSexList = new CopyOnWriteArrayList<OnRecvMsgSex>();
private static List<OnRecvMsgName> onRecvMsgNameList = new CopyOnWriteArrayList<OnRecvMsgName>();
public static void addListener(BaseListener listener){
if(listener instanceof OnRecvMsgAddress){
onRecvMsgAddressList.add((OnRecvMsgAddress)listener);
}
if(listener instanceof OnRecvMsgAge){
onRecvMsgAgeList.add((OnRecvMsgAge)listener);
}
if(listener instanceof OnRecvMsgHaHa){
onRecvMsgHaHaList.add((OnRecvMsgHaHa)listener);
}
if(listener instanceof OnRecvMsgXiXi){
onRecvMsgXiXiList.add((OnRecvMsgXiXi)listener);
}
if(listener instanceof OnRecvMsgSex){
onRecvMsgSexList.add((OnRecvMsgSex)listener);
}
if(listener instanceof OnRecvMsgName){
onRecvMsgNameList.add((OnRecvMsgName)listener);
}
}
/**
* 会移除所有的观察者,在程序退出时调用是一种好的编码习惯
* @param listener
*/
public static void removeListener(BaseListener listener){
if(listener instanceof OnRecvMsgAddress){
onRecvMsgAddressList.remove((OnRecvMsgAddress)listener);
}
if(listener instanceof OnRecvMsgAge){
onRecvMsgAgeList.remove((OnRecvMsgAge)listener);
}
if(listener instanceof OnRecvMsgHaHa){
onRecvMsgHaHaList.remove((OnRecvMsgHaHa)listener);
}
if(listener instanceof OnRecvMsgXiXi){
onRecvMsgXiXiList.remove((OnRecvMsgXiXi)listener);
}
if(listener instanceof OnRecvMsgSex){
onRecvMsgSexList.remove((OnRecvMsgSex)listener);
}
if(listener instanceof OnRecvMsgName){
onRecvMsgNameList.remove((OnRecvMsgName)listener);
}
}
}
下面是整个demo运行后的效果图:
输入的数字1--6代表上面的6中消息类型,输入数字,点击发送按钮后,目标会通知各自的观察者。
具体的代码可以在这里下载:https://github.com/215836017/ObservableDemo.git
同时欢迎大佬给予宝贵的建议和意见。