在android中,或者说java中,监听模式都是非常常见的。当你激发某个事件,常常你需要等待这个事件的返回。
如果这个事件是个异步事件,那么监听总是显得很有必要。
举个日常的例子,当你在android中连接网络并发送请求时,你就常常需要用到异步监听,用于监听并回调请求结果。这个就是异步回调。
观察者模式与回调模式有很多的相似处,简单对比就是:回调是一对一的关系,只监听一个事件;观察者模式则是一个主题,可以有多个监听,当主题变化时,向所有(也可以试部分)这些监听发出变化通知,观察者模式是一对多的关系。
以下是实例演示:
一、回调模式
这里演示一个不常用到的、但有些特色的方法。
用户a发送广播A,当其他用户(b,c,d,e,f等)接受到广播A后,回应该用户a一条广播B。用户需要在接受到广播B的时候,做一些UI操作。
这里设计的时候,我们把用户a接受广播的类独立出来,如下:
package com.example.broadcastwithobserver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MineBroadCastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("com.broadcast.test")){
Toast.makeText(context, "广播接收器接收到广播了!!!", 0).show();
GlobalVar.tag=1;
}
}
}
这个时候,我们遇到一个问题:我如何在这个广播中更新UI呢?挺麻烦的一件事(因为没有写成内部类...)。
想个办法,定义一个变量,在广播接收到后,修改这个变量的值。而我们再写个监听方法,监听该变量的值。当值变为我们预期的时候,就是接收到广播了。
public void tagChangeListener(BroadListener listener){
if(GlobalVar.tag==1){
listener.onSuccess();
}
}
监听接口如下:
package com.example.broadcastwithobserver;
public interface BroadListener {
public void onSuccess();
public void onFail(String msg);
}
如何使用呢,在MainActivity.java中:
package com.example.broadcastwithobserver;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn=(Button)findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
tagChangeListener(new BroadListener() {
@Override
public void onSuccess() {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "监听接收到广播了!!", 0).show();
GlobalVar.tag=0;
}
@Override
public void onFail(String msg) {
// TODO Auto-generated method stub
}
});
sendBroadcast(new Intent("com.broadcast.test"));
}
});
}
public void tagChangeListener(BroadListener listener){
if(GlobalVar.tag==1){
listener.onSuccess();
}
}
}
通过以上的方法,能在UI界面轻易修改UI等。
二、观察者模式
简单的说就是:一个主题,该主题自带被订阅、被取消订阅、通知这三个功能。而这个主题可以被多个观察者订阅,从而形成一对多的关系。
根据这描述我们先写下主题和观察者的接口(一般写为接口或者抽象类)。
主题:
package com.example.broadcastwithobserver;
/**
* 被观察主题
* @author 战国
*
*/
public interface Subject {
public void addObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObservers();
}
观察者:
package com.example.broadcastwithobserver;
/**
* 观察者
* @author 战国
*
*/
public interface Observer {
public void update(String msg);
}
以下实现以上的接口:
被观察主题实现接口方法:
package com.example.broadcastwithobserver;
import java.util.ArrayList;
import java.util.List;
public class SubjectImp implements Subject{
private List<Observer> list=new ArrayList<Observer>();
private String msg;
@Override
public void addObserver(Observer observer) {
// TODO Auto-generated method stub
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
// TODO Auto-generated method stub
int index=list.indexOf(observer);
if(index>=0){
list.remove(index);
}
}
@Override
public void notifyObservers() {
// TODO Auto-generated method stub
for(Observer observer:list){
observer.update(msg);
}
}
public void setMsg(String msg){
this.msg=msg;
notifyObservers();
}
}
观察者实现接口1:
package com.example.broadcastwithobserver;
public class ObserverImp implements Observer{
Subject subject;
public ObserverImp(Subject subject){
this.subject=subject;
subject.addObserver(this);
}
@Override
public void update(String msg) {
// TODO Auto-generated method stub
System.out.println("收到:"+msg);
}
}
观察者实现接口2:
package com.example.broadcastwithobserver;
public class ObserverImp1 implements Observer{
Subject subject;
public ObserverImp1(Subject subject){
this.subject=subject;
subject.addObserver(this);
}
@Override
public void update(String msg) {
// TODO Auto-generated method stub
System.out.println("收到:"+msg);
}
}
如何使用:
SubjectImp subjectImp=new SubjectImp();
ObserverImp observerImp=new ObserverImp(subjectImp);
ObserverImp1 observerImp1=new ObserverImp1(subjectImp);
subjectImp.setMsg("ok");
</pre><pre>
三、源码
http://download.csdn.net/my/uploads