Android 模块化总结_android模块化-程序员宅基地

技术标签: 组件化开发  android gradle配置  android 组件化  Android  

好久没写博客了,最近一直在写新项目。这两天基本上把该完成的都完成的差不多了。
正好新项目用到了很多以前没有用过的技术,在此总结一下。

本文我们先来说一下一下模块化。模块化很早就有了,网上也有很多例子。讲的都非常好,我这里也只是把自己在实际使用的情况做一下记录。

因为本来公司项目是多个角色多种任务都在一个App中的。结果等我快完成的差不多的时候,老大说了,要拆开,每个角色单独拆成一个App。
我都快写完了你告诉要拆开?

需求分析(模块划分)


首先我们来分析一下,这个项目实际上是有4个角色,每个角色的任务是不同的,但是像登录,注册,图片上传,消息推送,导航等一些逻辑是基本上一模一样的。也就是说其实只有任务模块是不同的,其他模块的逻辑基本类似。
如果我按照以前的写法,所有的逻辑都是在app模块中的。如果拆成4个App的话,也就是意味着我要复制4分代码,然后没分代码都改一下。这么做实在是有些不合适。
那既然是只有任务模块区分较大,其他模块逻辑基本一样,那么,更好的办法就是把一些业务单独的作为module,然后项目直接依赖就可以了。
于是,我们可以根据业务来划分一下module。(模块的划分根据自身的业务去制定,我这里只是举个例子)
首先我们肯定要有一个common的模块,该模块是一些共用的代码,比如对BaseActivity、BaseFragment、网络框架等业务的封装。 (common)
然后任务肯定单独是个模块 (taskModule)
登录,注册,注销等业务可以放到用户模块中 (userModule)
消息,通知这些可以放到消息模块中 (messageModule)
导航我这里是集成的高德地图的SDK,对地图相关的业务可以单独封一个地图模块,方便以后其他项目使用 (gaodemaplib)
还有一些项目中使用的自定义view的东西,我们也是可以服用的,我这里也单独作为一个模块了 (custom_view)

好了基本上根据业务需求划分了这几个模块。
这里写图片描述
如图所示,大概结构就是这样。

这样一划分之后,实际上我们的绝大多数业务都是在各个module中完成的,而app则相当于一个组装的module,只需要配置一下启动页面和处理少量的逻辑就可以了,然后剩下的module我们可以直接通过import module的方式复用。这样也大大降低了耦合性。
对于我这个项目,我只需要完成一个app的逻辑,然后其他app依赖通用的module即可。基本上不需要做改动。

统一的gradle配置


模块划分完毕后我们需要解决的就是一些第三方库的依赖,以及默认的一些gradle配置了。
gradle是基于Groovy语言的,用于编写脚本。作为一名Android开发人员,我们很有必要去学习了解一下Groovy。
在我们平时项目中,我们经常会跟gradle文件打交道,因为Android Studio默认就是用gradle来进行构建的,我们在开发中也会对一些gradle文件进行编辑。
比如,依赖一些第三方的库,指定Android的版本,多渠道打包,指定签名文件等等。

首先我们先来解决统一配置的问题,我们多个模块之间对第三方的依赖应该保持一致,特别是官方的support包,必须保持一致,不然编译时会提示版本不一致的错误,关于版本不一致的解决办法可以看我之前的一篇博客
com.android.support冲突的解决办法

首先我们可以新建一个文件,用于声明android默认的配置项,签名文件的信息,以及依赖的第三方库的版本号。
例如
新建一个config.gradle文件,该文件主要是用来声明一些共用的变量。

这里写图片描述
类似于这样


ext {

    /*defaultConfig*/
    compile_sdk_version = 27
    min_sdk_version = 16
    target_sdk_version = 27
    constraint_version = "1.0.2"
    version_code = 101
    version_name = "1.0.1"
    multiDexEnabled = true

    /*dependencies*/
    android_support = "27.1.1"
    butterknife = "8.5.1"
    eventbus = "3.1.1"
    glide = "4.7.1"
    permission = "2.0.0-rc10"
    retrofit = "2.4.0"
    ok_http = "3.10.0"
    rx_android = "2.0.2"
    rx_java = "2.1.4"
    rxlifecycle = "2.2.1"
    dagger2 = "2.16"
       
      /*等等*/


}

然后我们在project的build.grdle中引用该文件。

apply from: file('config.gradle')

这里写图片描述

注意路径不要错了,这样引入后我们就可以引用声明的变量了。

然后在module中的build.gradle中就可以使用我们声明好的变量了,这样一来,我们所有模块的版本就保持一致了,而且修改版本号的话只需要修改config.gradle中的变量值即可。
使用方法
这里写图片描述
这里写图片描述

模块的单独调试与相互依赖

在多人开发的模式下,可能每个人负责一个module,那么在调试的时候,我们需要把module单独作为一个application来调试。

这个时候,我们就需要准备两套清单配置文件。一套用于作为module时使用,另外一套作为application时使用,作为application时我们需要在清单配置文件中设置启动页面,主题等,而作为module的话,只需要声明一下需要的页面即可。

以userModule为例:

准备两套清单配置文件:
在这里插入图片描述
debug模式下的清单配置文件需要指定启动页,主题等

声明一个变量用来确定当前模块是不是一个module,例如

可以在跟目录的gradle.properties文件中声明,用起来也比较方便

isUserModule = true  //true表示当前是个library,false则表示是个application

user模块的build.gradle

我们需要根据是否是module来确定当前模块的类型

if (isUserModule.toBoolean()){
    apply plugin: 'com.android.library'
}else{
    apply plugin: 'com.android.application'
}

根据类型加载不同的清单配置文件:

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
            if (isUserModule.toBoolean()) {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            }
        }
    }

其他模块依赖的时候:
在这里插入图片描述
如果类型为module,则依赖

    if (isUserModule.toBoolean()) {
        implementation project(':user')
    }

这样一来,我们就可以方便的切换当前模块的类型了,也方便我们单独测试。

模块之间的通讯


关于模块之间的通讯,我采用的是使用阿里巴巴开源框架ARouter来解决,通过该框架我们可以实现不同模块之间的页面跳转,传值等。
ARouter Github

详细的使用方法直接查看官方文档即可,这里就不细说了。

建议:我们可以把路由配置信息放到公共库中,这样方便模块之前的跳转


实际上模块化开发的细节还有很多,说的再多都不如自己亲自写一写。
总得来说,模块化的好处就是是的业务划分的比较清晰,方便维护,同时有一定的复用价值,如果公司中有私服的话可直接把耦合低的公用模块上传上去,直接远程依赖使用,往组件化的方向走


如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yuzhiqiang_1993/article/details/80664398

智能推荐

10.1 UiPath代码调用活动Invoke Code的介绍和使用_uipath 调用vb.net-程序员宅基地

文章浏览阅读4.6k次。代码调用(Invoke Code)的介绍使用Invoke Code可以同步调用VB.NET或C#的代码,可以选择将其传递给in参数列表。此活动还可以将参数返回给调用方的工作流二、Invoke Code在UiPath中的使用打开设计器,在设计库中新建一个Sequence,为序列命名及设置Sequence存放的路径,然后在Activities中搜索Assign, 并将其拖至设计区,在”To”属..._uipath 调用vb.net

imx6u gpio随笔-程序员宅基地

文章浏览阅读272次。26章“Chapter 26 General Purpose Input/Ouput(GPIO)用作哪个外设就复用为哪个外设功能即可。能复用什么外设的话可以直接查阅《IMX6ULL。是其中的一种,我们想要把 GPIO1_IO00。来点个灯、作为按键输入啥的就是使用其 GPIO(如果我们要编写代码,设置某个 IO。、SRC_SYSTEM_RESET 和。的复用功能的话就需要查阅第。这两种寄存器都是配置 IO。比如 GPIO1_IO00。以后还需要对其 GPIO。对应的复用配置寄存器。

Django模板语言(三)_django模板 by as-程序员宅基地

文章浏览阅读160次。cycle每次遇到这个标记时,都会产生一个参数。第一次遇到时产生第一个参数,第二次遇到时产生第二个参数,以此类推。一旦用尽所有参数,标签就会循环到第一个参数,并再次生成它。_django模板 by as

DLMS/COSEM user guide_dlms user association (ua) books-程序员宅基地

文章浏览阅读2.2k次。jDLMS User GuideTable of Contents1. General1.1. Logical Devices1.2. Client Address1.3. Object addresses1.4. Accessing data2. Using jDLMS2.1. Entry point_dlms user association (ua) books

初学matlab和数字图像处理_imshow ylable-程序员宅基地

文章浏览阅读818次。一、matlab中,图像以矩阵形式存储。对图像操作,就是对矩阵操作。I(i,j)是矩阵的点(i,j)处的灰度值,I是图像矩阵。二、关于傅里叶变换:fft2(), ifft2()函数fft2()函数为二维快速傅立叶变换函数;ifft2()函数为二维逆快速傅立叶变_imshow ylable

可调电阻封装图_电子元器件封装名称和图形,工业美感十足(推荐收藏)-程序员宅基地

文章浏览阅读731次。元器件封装的构建是PCB设计中的一个重要环节,小小的一个错误很可能导致整个板子都不能工作以及工期的严重延误。常规器件的封装库一般CAD工具都有自带,也可以从器件原厂的设计文档、参考设计源图中获取。封 装 名 称 与 图 形 如 下No.1晶体管No.2晶振No.3电感No.4接插件No.5Discrete ComponentsNo.6晶体管No.7可变电容No.8数码管No.9可调电阻No.10电..._继电器的封装命名

随便推点

原生js实现大屏数字上下滚动效果,支持随机多位数字-程序员宅基地

文章浏览阅读193次。在大屏项目中经常需要实现那种数字上下滚动的效果,普通的数字随机滚动在UI组件(例如View Design中)里,或者是countUp插件中(Vue3数字滚动插件vue-countup-v3)注:本段代码是以原生js实现,若项目需要,可以自行转为Jquery形式或者Vue中的v-for生成。html部分只定义一个简单的容器,几个数字是靠js实现的,有更大的灵活性。

SAP ABAP编程 MOVE-CORRESPONDING将一个结构中的数据赋予另一个结构中-程序员宅基地

文章浏览阅读3w次,点赞7次,收藏11次。MOVE-CORRESPONDING用于将一个结构中的数据赋予另一个结构中的对应字段,只能存一行数据。所以使用时应该是如下形式:TABLES: spfli.DATA: yp_wa LIKE spfli, yp_tab LIKE TABLE OF spfli.TYPES: BEGIN OF sp, sel TYPE c. INCLUD_move-corresponding

cf两边黑屏怎么解决win10_临时解决win10_1903远程桌面黑屏bug-程序员宅基地

文章浏览阅读196次。作为一个macos用户,我保留了一个windows平台的旧电脑来运行一些windows only的应用程序。两台电脑之间通过windows远程桌面(RDP)进行连接。结果,前一阵子升级到1903之后就出bug了......症状:使用RDP客户端登录后远程电脑黑屏,鼠键都可以正常响应......原因这事又是微软的锅......显示驱动程序会报告它们加载能力上限。在以前Windows版本中会报告数据未...

计算机房档案管理,计算机档案管理与控制措施-程序员宅基地

文章浏览阅读157次。计算机是工业化时代和信息化时代的一种必然产物,在企业档案管理过程中具有重要作用,档案管理的效率提高离不开对于信息化时代的计算机管理方式的合理应用,受限于多种影响因素,计算机档案管理依然显得有些混乱,因此笔者的主要目的就是提供计算机档案管理的理论基础,实现新的技术条件下人们对于计算机档案管理的重新认识,并且提高其管理效率,使得大量的档案管理工作变得相对简单,保证档案的完整性,这样才能为人力资源的管理..._计算机中心档案

unity3d 改变脚本名称_Unity3D脚本中文系列教程(一)-程序员宅基地

文章浏览阅读439次。一、 脚本概览这是一个关于unity内部脚本如何工作的简单概览。Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成的。在脚本对象内部不同志的函数被特定的事件调用。最常用的列在下面:Update:这个函数在渲染一帧之前被调用,这里是大部分游戏行为代码被执行的地方,除了物理代码。FixedUpdate:这个函数在每个物理时间步被调用一次,这是处理基于物理游戏的地方。在任何函数之外的代码:在任..._创建unity脚本 改名

pyqt 实现对label属性修改及动态布局_pyqt label更改文字-程序员宅基地

文章浏览阅读4.7k次。实现这个的方法主要是创建不定数目的标签,及信息的传递。_pyqt label更改文字

推荐文章

热门文章

相关标签