组件化开发
Android项目中代码量达到一定程度,编译将是一件非常痛苦的事情,短则一两分钟,长则达到五六分钟。Android studio推出instant run由于各种缺陷一般情况下是被关闭的……
组件化开发可以有效降低代码模块的耦合度,使代码架构更加清晰,同时模块化的编译可以有效减少编译时间,当然总的编译时间是不会减少的,只是App模块化之后开发某个模块时,只需要编译特定模块,可以快速编译调试。
组件化分为一个APP,一个library和多个moudler
Library里面放着第三方库,app和moudler分别持有library。
在gradle.properties里面添加控制
#控制application和library状态切换 isUserModule = false
APP的build里面添加
if(!isUserModule.toBoolean()){ api project(':my') }用来控制
每个moudler的build里面添加
if (isUserModule.toBoolean()) { apply plugin: 'com.android.application' } else { apply plugin: 'com.android.library' }控制moudler是最为library存在还是独立的app存在
以app形式的时候添加
if (isUserModule.toBoolean()) { applicationId "com.example.my" }
AndroidManifest文件需要创建两个用来区分library和app,添加
sourceSets { main { if (isUserModule.toBoolean()) { manifest.srcFile 'src/main/moudler/AndroidManifest.xml' } else { manifest.srcFile 'src/main/AndroidManifest.xml' } } }
library的AndroidManifest文件只保留一个zheme属性,activity的启动方式去掉,不然运行的时候也会创建这个library的app
app与moudler之间的通信可以通过阿里的ARouter路由框架来实现
ARouter集成
在library的build里面添加
api 'com.alibaba:arouter-api:1.4.0' //这个在library中导入即可
创建一个application文件在里面初始化ARouter
if (BuildConfig.DEBUG) { // 日志开启 ARouter.openLog() // 调试模式开启,如果在install run模式下运行,则必须开启调试模式 ARouter.openDebug() } ARouter.init(this)在销毁的方法里面destoryARouter
override fun onTerminate() { super.onTerminate() ARouter.getInstance().destroy() }
每个moudler里面添加
apply plugin: 'kotlin-kapt' kapt { arguments { arg("AROUTER_MODULE_NAME", project.getName()) } } kapt 'com.alibaba:arouter-compiler:1.2.2'
api 的版本和 compiler 的版本号需要用最新的。
如果这个moudler以app形式运行的话,这些需要注释掉,不然无法运行
ARouter跳转
1.无参跳转
ARouter.getInstance() .build("/ceshis/b") .navigation()
2.有参跳转
ARouter.getInstance() .build("/ceshis/b") .withString("i132", "2") .navigation()
通过with来传递不同类型的值,在接受的页面添加
@JvmField //必须加上,否则无法编译 @Autowired(name = "i132")
name后面跟的是传参的key值
每个页面的上面添加
@Route(path = "/my/myact")
path后面是路径,路径必须是二级,我们可以创建一个类来管理这些页面。
Fragment获取到activity的数据:
ARouter.getInstance().build("/app/vehfragment") .withInt("titleid",titleid) .navigation() as Fragment
不同module的一级路径必须不同,否则会导致一个moudle中的一级路径失效
ARouter还可以在跳转的时候设置拦截器功能
ARouter.getInstance() .build("/ceshis/b") .withString("i132", "2") .navigation(this@MainActivity,object :NavigationCallback{ override fun onFound(postcard: Postcard?) { //路由被发现时调用(被拦截器拦截时会调用) Log.i("awdawd","onfound") } override fun onLost(postcard: Postcard?) { //路由到丢失之后会调用(地址错误或者找不到对应的路径) Log.i("awdawd","onLost") } override fun onArrival(postcard: Postcard?) { //路由到达之后会调用(onfound执行后如果没拦截就会执行) Log.i("awdawd","onArrival") } override fun onInterrupt(postcard: Postcard?) { //路由被拦截时调用 Log.i("awdawd","onInterrupt") } })
定义一个类,继承IInterceptor 使用@Interceptor注解,ARouter的拦截器可以设置拦截器的优先级,通过priority设置,priority值越小优先级越高,值必须是int类型,优先级的等级不能有两个是一样的不然会崩溃。
在process里面,我们可以通过postcard.path来获取我们跳转的路由路径地址来进行拦截判断。
if (postcard?.path.equals(Constance.ACTIVITY_SECOND)) {
Log.e("UseIInterceptor", "进行了拦截处理:" + postcard?.path.toString())
//拦截路由
callback.onInterrupt(null)
ARouter.getInstance().build(Constance.ACTIVITY_LOGIN).navigation()
}else{
//交还控制权
callback.onContinue(postcard)
}
callback.onInterrupt(null) 这句代码可以让路由被拦截,然后我们进行拦截后的操作,最后通过callback.onContinue(postcard) 进行交还控制权,如果不交还控制权,就算拦截条件不满足,他也不会进行后续的路由跳转了
我们如果没有拦截器拦截并且路径正确的话,正常步骤应该是先onFound()方法再onArrival()方法,如果被拦截的话会执行onFound()和onInterrupt()方法。
如果路由的路径错误的话,会直接调用 onLost方法。