Android组件化实战

什么是组件化开发?个人理解是一种高内聚低耦合的开发模式。在移动开发里,它将一个大功能整体进行拆分,分别进行单独调试,最后再合并打包
我向大家极力推荐使用组件化。因为无论你使用的是何种语言,开发的是什么项目,都有可能面对项目迭代中的各种高度耦合,而且随着开发人员数量的增多或者人员的调度,这种问题会越来越严重。最后在开发过程中,你就不得不在各个模块间跳来跳去,再加上AS本身编译速度那么慢,岂是一个呵呵能够代表此刻复杂的心情?组件化就可以比较好的处理了这个问题,你开发A,他开发B,我开发C,我们用的公共库是同一个,各自独立开发独立测试,完事之后再合并,相互不受影响。
每次看别人的文章,都会对比下插件化跟组件化的区别,没错,看上去确实两者功能差不多,但是我觉得这个没啥好比较的。抛开demo来说,不是每个人都能理解插件化的技术原理,出了bug谁来改?反正我是不会改。。。组件化毕竟在原生控制范围内,只要进行合理的设计即可,换句话说,难度不大。。。

Android组件化实战_第1张图片
组件化大致思路

如何进行组件化

这里扯个淡,请原谅我不喜欢直接用老师这个词。《师说》中:“师者,所以传道授业解惑也”。一说到组件化全是冯森林老师,总觉得有点怪怪的,还是直接称呼oasisfeng比较习惯
之前我们开发过程中,可能不自主的就往组件化这种模式靠近。我在开发一个项目的时候,用到了美恰这个意见反馈SDK,当时就将它抽成一个aar,然后主工程直接startActivity,完事,看起来很方便。但是aar是需要编译的,这个又回到之前说的那个情况上去了,慢!慢!非常慢!oasisfeng就很牛逼的提供了一个思路:利用状态位去分别做不同的事情。具体来说就是区分Debug模式和Release模式,在Debug模式下,各个Module作为Application单独运行,而在Release模式下则作为Library,提供给主App进行依赖。这样相互没有影响,非常实用。对我来说,虽然还是需要编译2次,但是已经不都是整体编译了,时间也节省一些

Android组件化实战_第2张图片
整体结构


在这里,app就是主工程,modulea就是一个独立的业务,moduleres就是公共库

下面是重点,讲流程了,也不复杂

  1. 定义一个全局gradle变量,在gradle.properties中定义
    # 是否处于调试状态
    isDebug=false
  2. 回到我们的modulea的build.gradle中,你要是不放心可以打印下isDebug这个值
    println isDebug.toBoolean()
    随后我们就通过这个值来处理它的类型,当处于debug的时候,它就是一个独立的可执行的模块,反之就是一个普通的库
    if (isDebug.toBoolean()) {
     apply plugin: 'com.android.application'
    }else {
     apply plugin: 'com.android.library'
    }
    还有就是debug跟release的处理我们需要注意下,作为一个库跟作为一个独立工程,他们可能需要加载不同的资源文件或者类文件。最直接的一个情况就是我们再debug的时候,可能需要DebugActivity去进行测试,你肯定不希望将这个DebugActivity达到正式版里面去。这里展示一下如何根据不同值去加载不同的资源文件以及如何排除不需要参与打包的类文件
    sourceSets {
     main {
        if (isDebug.toBoolean()) {
             manifest.srcFile 'src/main/debug/AndroidManifest.xml'
             res.srcDirs = ['src/main/debug/res']
         }
         else {
             manifest.srcFile 'src/main/release/AndroidManifest.xml'
             java {
                 //排除java/debug文件夹下的所有文件
                 exclude 'debug/**'
             }
         }
     }
    }
    来看看最终modulea的结构
    Android组件化实战_第3张图片
    modulea的结构

    这里还有一个小技巧
    resourcePrefix "modulea_"
    通过这个设置可以将你的资源名称进行检查,如果不满足前缀为"modulea_",则有红色波浪线提示

    resourcePrefix
  3. 回到主工程App的build.gradle中,同样进行处理,当处于debug的时候,就不去加载modulea,反之则加载
    if (isDebug.toBoolean()) {
     compile project(':moduleres')
    }else {
     compile project(':modulea')
    }
    这里说明下,modulea中包含moduleres,所以不需要加载这么多遍

组件与组件之间如何交互

其实说白了也很简单,我们一般通过隐式调用跟显示调用来启动一个Activity。但是在这里,不管采用何种调用方式,肯定都要在主App中有个地方去维护这个对应关系。但是还有一个问题要考虑,如果参数过多putExtras也是很烦的,而且这个又要找地方保存需要的变量了。。。。。。提供给大家一个思路,你还记得怎样实现点击手机浏览器里的链接直接启动App吗?是的,只要在data里配置相应的scheme以及host,或者额外的path什么的,就可以访问到指定类了
这里推荐大家使用ActivityRouter这个库,在github上有它完整的使用Demo,足以依葫芦画瓢实现。简单的介绍下,ActivityRouter提供了一个中间件,通过中间件解决本地业务组件之间的通信与组件间直接引用、依赖混乱的问题,它只负责挂接节点,不涉及挂接点具体业务的任何逻辑。

参考文章

关于Android业务组件化的一些思考
Android组件化开发实践

你可能感兴趣的:(Android开发工具)