Android通信

简易App内部消息通信

2018-07-04  本文已影响12人  ZZombiee

之前文章介绍了用广播去通知界面更新,这会儿又无法满足我的要求

广播进行消息通信

广播的好处

我现在又为什么不满足于广播?

我的需求

为此我需要打的地基

大致的结构


目录结构.png

Show Code!

/**
 * Created by Gss on 2018/2/12 0012.
 */

public abstract class BaseStore<T, E extends BaseResponder> {
    public final ArrayList<E> observerList = new ArrayList();
    private static BaseStore INSTANCE;

    public void registerObserver(E t) {
        if (checkValid(t))
            observerList.add(t);
    }

    private boolean checkValid(E t) {
        return t != null;
    }

    public void unRegisterObserver(E t) {
        if (checkValid(t) && observerList.contains(t))
            observerList.remove(t);
    }

    public abstract void notifyObservers(T t, Object objects);
}

Store目的很简单,将观察者一一添加到集合里
观察者必须实现接口Responder

/**
 * Created by Gss on 2018/2/12 0012.
 */

public interface BaseResponder<T> {
    void receiveResponse(T t);

    String[] bindAction();
}

只有两个方法,需要观察的行为(数组返回),响应receiveResponse(重载后面会有)

/**
 * Created by Gss on 2018/2/12 0012.
 */

public abstract class DispatchManager<T extends ActionType> {
    public void dispatch(int type) {
        dispatch(type, null);
    }

    public abstract void dispatch(int type, Object data);
}

行为管理器,一个是带参数的方法,一个是不带参数的方法

以上是基类的简易结构,具体实现全在GlobalStore中,如下

/**
 * Created by Gss on 2018/2/12 0012.
 */

public class GlobalStore extends BaseStore<Action, Responder> {
    private static GlobalStore store;
    private Map<Responder, Map<Class, Method>> responderMethod = new HashMap<>();

    public static GlobalStore getStore() {
        if (store == null) {
            store = new GlobalStore();
        }
        return store;
    }

    @Override
    public void notifyObservers(Action action, Object objects) {
        if (objects != null)
            action.getAction().setData(objects);
        postMessage(action, objects);
    }

    @Override
    public void unRegisterObserver(Responder t) {
        super.unRegisterObserver(t);
        responderMethod.remove(t);
    }

    private void postMessage(Action action, Object objects) {
        try {
            for (Responder responder : observerList) {
                for (String s : responder.bindAction())
                    if (s.equals(action.getAction().getAction())) {
                        String o = CUtil.getInterfaceType(responder);
                         if (objects == null || (objects != null && objects.getClass().getSimpleName().equals(o))) {
                            responder.receiveResponse(objects);
                        }
                        //如类型不对,则查找观察者是否有重载的方法
                        else if (responderMethod.get(responder) == null || responderMethod.get(responder).get(objects.getClass()) == null) {
                            getMethod(responder, objects);
                        }
                        //如类型不对,且map中已存储了map
                        else if (responderMethod.get(responder).get(objects.getClass()) != null) {
                            responderMethod.get(responder).get(objects.getClass()).invoke(responder, objects);
                        } else
                            responder.receiveResponse(null);
                        break;
                    }
            }
        } catch (Exception e) {
        }
    }

    private boolean getMethod(Responder responder, Object c) {
        try {
            Method m = responder.getClass().getMethod("receiveResponse", c.getClass());
            m.invoke(responder, c);
            if (responderMethod.get(responder) == null)
                responderMethod.put(responder, new HashMap<Class, Method>());
            responderMethod.get(responder).put(c.getClass(), m);
            return true;
        } catch (Exception e) {
            responder.receiveResponse(null);
        }
        return false;
    }

}

方法体含义

这样管理以后,首先,不存在传输的对象需要序列号的问题;其次,行为完全是开发者自定义的,可以回溯;再者可以对其进行扩展(比如加入严格模式类型不对不调用响应方法之类的)

最后来放出我的使用示例


按钮发生事件.png

两个按钮分别发送申请事件和同意事件


单事件.png

注册单事件


多事件重载5.png

注册多事件,并重载了Interger参数的响应体


发送消息.gif

可以看到,注册了单事件的界面接收不到同意行为,而多事件可以
并且注册了多事件行为的界面本身没有Interger类型的响应体,只是重载了它,一样能成功收到

以上就是简易的通信框架了,如果好用的话,会继续优化

上一篇 下一篇

猜你喜欢

热点阅读