观察者模式我就不累赘的讲了。网上有很多。还没用过的,只能说,抓紧补起来。
一、观察者模式,当然离不开观察者。这里举例,在需要更新界面的地方添加观察者。可以在fragment,activity,dialog等地方,都可以添加观察者 ,有点想实现监听接口。都差不多。就看你怎么理解。
public class MainActivity extends AppCompatActivity implements Observer {
//在需要的地方去实现observer接口。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这里添加观察者 表示,我时刻关注着你。你有啥事,通知我一声。
NotifyManager.getNotifyManager().addObserver(this);
startThread();
}
//这里模拟在其他界面或者子线程中的被观察者。被观察者这个时候开始,要发消息了。code 为TYPE_MAIN ,可以自定义。往下看
private void startThread() {
new Thread(new Runnable() {
@Override
public void run() {
NotifyMsgEntity msgEntity = new NotifyMsgEntity();
msgEntity.setCode(NotifyManager.TYPE_MAIN);
msgEntity.setData(1);
NotifyManager.getNotifyManager().notifyChange(msgEntity);
}
}).start();
}
//observer的方法,用于处理被观察者发来的通知。
@Override
public void update(Observable o, Object data) {
if (data == null || !(data instanceof NotifyMsgEntity)) {
return;
}
NotifyMsgEntity entity= (NotifyMsgEntity) data;
int code = (int)entity.getData();
int type =entity.getCode();
if(NotifyManager.TYPE_MAIN==type){
Toast.makeText(this, "code="+code, Toast.LENGTH_SHORT).show();
}
}
}
二、这么多观察者,各个需求都不一样呀。所以,这里整合一下。做个管理,毕竟,被观察者,可能在主线程,也可能在子线程中。
public class NotifyManager extends Observable {
/**
* 被观察的事件类型
*/
public static final int TYPE_MAIN = -1;// 其他未知
private static NotifyManager mNotifyManager;
/**
* 获取通知管理器
*
* @return
*/
public static NotifyManager getNotifyManager() {
if (mNotifyManager == null) {
mNotifyManager = new NotifyManager();
}
return mNotifyManager;
}
private NotifyManager() {
}
/**
* 事件发生后通知监听者
*
* @param code :事件代码号
*/
public void notifyChange(int code) {
NotifyMsgEntity msgEntity = new NotifyMsgEntity();
msgEntity.setCode(code);
notifyChange(msgEntity);
}
/**
* 事件发生后通知监听者
*
* @param msgEntity 需要发送的消息数据
*/
public void notifyChange(final NotifyMsgEntity msgEntity) {
UIUtils.runInMainThread(new Runnable() {
@Override
public void run() {
setChanged();
notifyObservers(msgEntity);
}
});
}
}
三、判断是不是在主线程(UI线程)
public class UIUtils {
public static int getMainThreadId() {
return BaseApplication.getMainThreadId();
}
public static Handler getHandler() {
return BaseApplication.getHandler();
}
// 判断是否是主线的方法
public static boolean isRunInMainThread() {
return getMainThreadId() == android.os.Process.myTid();
}
// 保证当前的UI操作在主线程里面运行
public static void runInMainThread(Runnable runnable) {
if (isRunInMainThread()) {
// 如果现在就是在珠现场中,就直接运行run方法
runnable.run();
} else {
// 否则将其传到主线程中运行
getHandler().post(runnable);
}
}
}
四、BaseApplication 中,记录全局变量和对象,handler 在oncreate里创建实例。
public classBaseApplication extends Application {private staticHandler handler;
@Overridepublic voidonCreate() {
super.onCreate();
handler= newHandler();
}public staticContext getContext(){returngetContext();
}public static intgetMainThreadId(){returnandroid.os.Process.myPid();
}public staticHandler getHandler(){returnhandler;
}
}
五、消息实例。这个,也是可以随意定义的。
public class NotifyMsgEntity {
private int code;// 消息类别代码
private Object data;// 消息数据实体
private Object content;
public NotifyMsgEntity() {
super();
}
public NotifyMsgEntity(int code, Object data) {
super();
this.code = code;
this.data = data;
}
public NotifyMsgEntity(int code, Object data, Object content) {
this.code = code;
this.data = data;
this.content = content;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Object getContent() {
return content;
}
public void setContent(Object content) {
this.content = content;
}
}
最后,按需使用吧。
===============================shoneworn================================================