一个组件化的项目,会将业务进行细化的拆分,通用的功能封装在通用的模块中,不同通用功能模块之间是平级的关系,不同的业务模块会按需依赖其中几个通用模块。
如上图所示,业务A无法调用业务B中的API,同样业务B也无法打开业务A中的页面,这两个业务模块是独立的,通用模块之间也是如此。
模块间如果需要访问API,得建立强依赖关系,项目的耦合度会变得非常高,通用模块因为需要多种依赖而失去了它通用的特性。
因此我们需要一种松耦合的方式,建立平级模块间的通信方式,实现组件化。
模块间需要通信的场景有很多种,例如访问页面,UI事件通知、回调等等。本文为大家介绍一个我自己写的帮助实现项目组件化的库:KRouter,它是一个非常轻巧、高效、稳定的安卓组件库,它使用kotlin编写,能够运用于java、kotlin甚至混编项目,它支持多模块,通过注解的方式,能非常方便地解决无依赖关系模块间页面访问、API调用问题。
在写本文时,KRouter已经开发到1.0.4版本,且仍然在维护中,读者可以访问项目github地址:https://github.com/jamgudev/KRouter,获取最新的版本信息。
如果您觉得该库实用的话,欢迎start和fork,如果您发现该库存在bug或还有改进的地方,欢迎提交issues或提交pull requests!
接下来,我为大家简单说下如何使用KRouter。
正文
如何使用
首先引入该库,编辑你的工程build.gradle文件,在文件中添加插件地址:
buildscript {
dependencies {
classpath "io.github.jamgudev:krouter-plugin:1.0.4"
}
}
并在application module中引用插件:
plugins {
id 'com.jamgu.krouter.plugin'
}
添加完后,同步一下代码就可以使用KRouter的所有功能了。
你可能会疑惑,支持注解的库都需要注解处理器,为什么没有添加注解处理器的依赖就可以使用?
实际上添加其他依赖库的操作,com.jamgu.krouter.plugin
插件帮你自动完成了。我将其他依赖库的最新版本号内置在了插件中,你只需要使用最新版本的plugin插件,理应可以获得所需依赖库的最新版本。
你也可以在工程的build.gradle文件中指定依赖库的版本:
ext {
krouter_core_version = "1.0.4" // edit the version number you need
krouter_compiler_version = "1.0.3"
// flag whether to print compiler logs
krouter_compile_loggable = false
}
多模块支持
如果你除了主工程模块外,其他依赖模块也需要使用KRouter,只需要在相应模块的build.gradle中应用krouter插件即可:
plugins {
id 'com.jamgu.krouter.plugin'
}
简单使用
Activity路由
@KRouter(value = "setting_activity", intParams = {"userId", "gameId"}, stringParams = {"user_name"})
public class SettingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
}
}
// 简单调用
KRouters.open(context, "setting_activity");
// 带参数调用
KRouters.open(context, new KRouterUriBuilder("router")
.with("userId", 10000)
.with("gameId", 20010)
.with("user_name", "jamgu")
.build());
// startForResult
KRouters.openForResult(context, "setting_activity", 10010);
// activity routers api
Intent intent = KRouters.getRawIntent(this, "setting_activity");
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), (callback) -> {})
.launch(intent);
为Activity路由注册全局拦截器
KRouters.registerGlobalInterceptor(new IRouterInterceptor() {
@Override
public boolean intercept(@NotNull Uri uri, @Nullable Bundle bundle) {
Log.d(TAG, "uri = " + uri + " bundle = " + bundle);
return false;
}
});
当intercept()
方法返回true时,拦截本次路由,不会跳转。
Fragment路由
@KRouter(value = "main_frag", intParams = "col_id")
public class MainFragment extends Fragment {}
// 配置注解后可以通过main_frag获取该fragment实例
Fragment fragment = KRouters.createFragment(context, "main_frag");
Method路由
@MethodRouter(value = "get_some_state2")
public static boolean getSomeState(Map<String, Object> map, IAsyncMethodCallback<Boolean> callback) {
// do something
// 如果传递了参数,可以通过如下方式取
String userName = (String) map.get("userName");
long userId = Long.parseLong(map.get("userId").toString());
Log.d("jamgu", "hhhh userID = " + userId);
return false;
}
// 简单调用,不传递参数,此时map为null,
MethodRouters.invoke("get_some_state2");
// 带参数传递
boolean state = MethodRouters.invoke("get_some_state2", new MethodMapBuilder()
.with("userId", "12345")
.with("userName", "jamgu")
.build());
// 带参数传递,同时传递一个回调,回调位置由用户决定
MethodRouters.invoke("get_some_state2", new MethodMapBuilder()
.with("userId", "12345")
.with("userName", "jamgu")
.build(), new IAsyncMethodCallback<Integer>() {
@Override
public void onInvokeFinish(Integer integer) {
// 供其他地方指定的回调
}
});
MethodRouter限制较大,MethodRouter注解仅支持静态方法,只允许传递最多两个参数,传递的参数类型只能是Map类型,或者IAsyncMethodCallback类型,且不能同时传递两个Map类型或Callback类型。
例如你可以将MethodRouter注解运用到如下格式的静态方法中
@MethodRouter(value = "xxx")
public static void getSomeState() {
// 空返回类型,无需传递参数
return;
}
@MethodRouter(value = "xxx")
public static Integer getSomeState(Map<String, Object> map) {
// Integer返回值类型,可支持一个Map类型参数
// 调用时可以不传map,不传递时,map为null
return 0;
}
@MethodRouter(value = "xxx")
public static Integer getSomeState(Map<String, Object> map, IAsyncMethodCallback<Integer> callback) {
// 支持传递两个参数,若都不传递,则两参数为null
return 0;
}
KRouter的简单用法就说到这,更多用法就交给大家去探索了~
如果在使用KRouter时发现了bug或觉得有任何地方需要改进的,欢迎反馈!我需要你们的建议不断完善!
兄dei,如果觉得我写的还不错,麻烦帮个忙呗 😃
- 给俺点个赞被,激励激励我,同时也能让这篇文章让更多人看见,(#.#)
- 不用点收藏,诶别点啊,你怎么点了?这多不好意思!
拜托拜托,谢谢各位同学!