zoukankan      html  css  js  c++  java
  • android——使用观察者模式打造跨线程、跨界面等一对多通讯

    观察者模式我就不累赘的讲了。网上有很多。还没用过的,只能说,抓紧补起来。

    一、观察者模式,当然离不开观察者。这里举例,在需要更新界面的地方添加观察者。可以在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================================================

  • 相关阅读:
    对Spring 框架 AOP(面向切面)的理解
    页面自动刷新
    页面通过ajax传值到后台,后台返回值展示在页面输入框
    java中怎么跳出两层for循环
    人的三种思维角度
    我理解的战争(程序员是需要有立场的)
    我所理解的JavaScript中的prototype与__proto__、constructor
    一个"失速"项目的总结
    TDD学习笔记
    Java SQL动态生成库
  • 原文地址:https://www.cnblogs.com/shoneworn/p/7458833.html
Copyright © 2011-2022 走看看