靠着打代码,我终于走上了人生巅峰,看着支付宝里似乎永远花不完的余额,我不禁开始迷茫。后面的路在何方?
一阵恍惚,我从工位上醒了过来,夏日炎炎,办公室的风扇吹不走空气中的燥热。
妈呀果然是梦~~
一.背景 最近团队做一个提供 ocr 识别能力的 sdk 项目。身为一个普通码农,当然是领导说干啥就干啥,于是和算法对接吭哧吭哧打完了 身份证识别,手机号识别等卡证识别功能。开心,交付给了客户!!
不久领导又说搞个指尖识别的sdk提供给用户做指尖搜题用,和原来的项目放一块,搞个统一的能力sdk。但是输出sdk的时候要求剔除掉指尖识别之外的无关代码。为了赶进度挥洒之间,我又写完了,在打包的时候,直接拉了个新的输出分支剔除旧代码。就这样输出了。
后面又要一个新的sdk能力,图像质检 sdk 。
麻烦的问题就跳出来了:
怎么办呢~~
二.思考
这个问题说是问题也不是问题,无非是有点繁琐,维护好几个不同能力的独立分支就完事了。
但是我懒呀~~
聪明的我就想到了两个方法。
每个能力分出独立的模块,编译的时候打对应能力模块就好啦
使用gradle 配置编译不同的源文件,根据配置来打出包含不同源码的sdk
最后当然是选择了使用gradle sourceSets 配置的方式来编译不同的sdk源码啦。 为什么不选分模块呢?因为对外提供的是aar包,而不是maven仓库地址。所以存在多个能力多个aar包的情况,尽量提供少的aar包吧,方便用户方便自己。
三.开干
先剥离不同sdk的源代码,放在不同的文件夹下面。通用代码放在默认的java文件夹中。
这是一个细活,避免互相依赖,尽量依赖倒置,解开耦合,让每个sdk能力都能独立编译,并且能一起编译。
在 gradle.properties 中新增sdkType配置
1 2 3 4 5 6 7 8 9 10 11 12 ## 手机号,身份证银行卡等 #sdkType=ocr ## 图像质检 #sdkType=graphcheck ## 指尖检测 #sdkType=fingerdetect ## 依赖全部代码 sdkType=all
在 build.gradle 配置源文件路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 android { //...其他配置代码 sourceSets { main { //默认文件夹 def javaPaths = ["src/main/java"] def assetsPaths = ["src/main/assets"] def javaGraphCheck = "src/main/javaGraphcheck" def javaFingerDetect = "src/main/javaFingerdetect" def javaOcr = "src/main/javaOcr" def assetsGraphCheck = "src/main/assetsLens" def assetsOcr = "src/main/assetsOcr" def assetsFinger = "src/main/assetsFinger" if (sdkType == "graphcheck") { javaPaths.add(javaGraphCheck) assetsPaths.add(assetsGraphCheck) } else if (sdkType == "fingerdetect") { javaPaths.add(javaFingerDetect) assetsPaths.add(assetsFinger) } else if (sdkType == "ocr") { javaPaths.add(javaOcr) assetsPaths.add(assetsOcr) } else { javaPaths.add(javaGraphCheck) javaPaths.add(javaFingerDetect) javaPaths.add(javaOcr) assetsPaths.add(assetsGraphCheck) assetsPaths.add(assetsOcr) assetsPaths.add(assetsFinger) } java.srcDirs = javaPaths assets.srcDirs = assetsPaths } } }
修改编译产物的名称(为了直观区分打出来的是啥)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 android { buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' android.libraryVariants.all { variant -> variant.outputs.all { outputFileName = "sail_ocr-${version}-${sdkType}.aar" } } } } }
其他配置
dependencies 依赖 和 setting.gradle 中也可以根据 sdkType 来判断。如下就是我项目中的demo模块树。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 if (sdkType == "graphcheck") { include ':lensdemo' include ':module_graphcheck' include ':module_ocr' } else if (sdkType == "fingerdetect") { include ':demo_finger_detect' include ':module_scan_finger' include ':module_ocr' include ':module_base' include ':module_ui' include ':lib_base' include ':lib_utils' } else if (sdkType == "ocr") { include ':demo_ocr' include ':module_ocr' include ':module_base' include ':module_ui' include ':lib_base' include ':lib_utils' } else { include ':app' include ':demo_ocr' include ':lensdemo' include ':module_graphcheck' include ':module_scan_finger' include ':module_profile' include ':module_ocr' include ':module_base' include ':module_ui' include ':profile_photo_frame' include ':lib_base' include ':lib_utils' }
现在只需要在gradle. properties中修改sdkType的值,就可以直接编译出对应的sdk包
四.结尾 这样的工作并不难,做完之后却有小小的成就感。
抽出那么半天一天时间专门用来剥离代码,解除耦合,调试错误。琐碎得工作却让时间流逝得飞快。
很多事情都不难,只是迟迟没有人去做罢了。