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================================================

posted @ 2017-08-31 16:12  shoneworn  阅读(987)  评论(0编辑  收藏  举报