Skip to content

zongwu233/Summer

Repository files navigation

Summer

介绍

Summer是一个模块解耦框架,它解决了以下几个痛点:

1、模块与模块之间不再需要相互依赖

2、模块边界清晰化

使用

模块A

  • 在build.gradle加入
	compile 'com.meiyou:summer:1.0.4'
	compile 'com.meiyou:summer-compiler:1.0.4'
  • 定义接口:
@ProtocolShadow("ModuleBarStub")
public interface ModuleStub {
    public void testMethod(String msg, Context context, TextView textView);
    }

其中:

ProtocolShadow 是summer接口标识,意味着在编译时会被扫描到并做相应的处理

ModuleBarStub 则是协商的名字,模块B将使用这个字符串标识与之联系

模块B

  • 在build.gradle加入
	compile 'com.meiyou:summer:1.0.4'
	compile 'com.meiyou:summer-compiler:1.0.4'
  • 定义实现:
@Protocol("ModuleBarStub")
public class ModuleBar {
    
    public void testMethod(String msg, Context context,
                                        TextView textView) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        
    }
}

其中:

Protocol 是summer实现标识,意味着在编译时会被扫描到并做相应的处理

ModuleBarStub 则是与模块A协商的名字

  • 模块B调用模块A的方法:
 ProtocolInterpreter.getDefault().
                        create(ModuleStub.class)
                        .testMethod("oh this from main Activity!",
                                getApplicationContext(), textView);
                               

至此,模块A和模块B,在不相互依赖的情况下,完成了交互。

实现原理

通过编译期注解+java动态代理实现。 具体细节见代码。

缺点

之前可以通过implements interface 比较方便地获得子类方法的签名,现在没有IDE智能提示,写实际的实现类方法的时候,有点不方便。

混淆

-keep public class com.meiyou.framework.summer.data.** { *; }

提供模块间数据总线功能

提供类似于EventBus 的功能,但是属于模块间可用(也支持模块内自己通信)。用法类似于EventBus。除了要注意:

发送消息的模块,要对Event 的class做注解@Event("name")

在响应消息的模块的具体方法上,对方法注解@OnEvent("name")即可,方法名称不受限制,但是改方法的入参,必须与原始Event的class同构。

同构:具有相同的结构组成;相同的成员变量。

OnEvent注解支持MainThread和BackgroundThread。
示例:

事件源Event:

@Event("Account")
public class AccountDO {
    String nick = "ooooh";
    long userId = 2222;

    public AccountDO(String nick, long userId) {
        this.nick = nick;
        this.userId = userId;
    }

    public String getNick() {
        return nick;
    }

    public void setNick(String nick) {
        this.nick = nick;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }
}

接收改事件的对象需要注册,比如:

 ProtocolInterpreter.getDefault().register(testEvent);

多次调用该方法会自动去重,也可以调用下面方法检测是否已经注册:

boolean registered =  ProtocolInterpreter.getDefault().isRegister(testEvent);

发送该事件(可以在任何活动线程执行):

  ProtocolInterpreter.getDefault().post(new AccountDO("bg", 2222));

testEvent 的class里面有:

	@OnEvent("Account")
    public void process(MyAccount account) {
        ToastUtils.showToast(mContext,"module test get: "+account.getNick() + "," + account.getUserId());
    }

    @OnEvent(value = "Account",exec = OnEvent.Thread.BACK_GROUND)
    public void process2(MyAccount account) {
        LogUtils.d(TAG,"module test background get: "+account.getNick() + "," + account.getUserId());
    }

process() process2() 两个方法注册接收改事件,分别是在MainThread BackgroundThread里执行。

如果不指定OnEvent里的exec就意味着默认在mainThread执行。

About

Decoupled protocol for modules in Android App

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published