观察者模式我就不累赘的讲了。网上有很多。还没用过的,只能说,抓紧补起来。
一、观察者模式,当然离不开观察者。这里举例,在需要更新界面的地方添加观察者。可以在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 class BaseApplication extends Application { private static Handler handler; @Override public void onCreate() { super.onCreate(); handler= new Handler(); } public static Context getContext(){ return getContext(); } public static int getMainThreadId(){ return android.os.Process.myPid(); } public static Handler getHandler(){ return handler; } }
五、消息实例。这个,也是可以随意定义的。
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================================================