痛点 壳工程通过implementation 'com.alibaba:fastjson:1.2.76'的形式引入aar文件,而aar使用一个单独的业务工程开发,这种形式开发模式常见于组件化的工程中。这样做可以隔离代码,深度解耦,业务复用,节省编译时间。然而有时候我们需要在壳工程中进行aar联调,这时候我们就需要把aar工程的源码引入到壳工程中,在壳工程中做法如下:
在settings.gradle文件中添加如下配置
1 2 include ":moduleName" project(":moduleName" ).projectDir = file("源码路径" )
在app模块通过implementation project(":moduleName")方式引入
调试好后移除上面配置,发布版本。
这样做虽然能达到目的,但不够优雅,存在忘记恢复导致CI不能正确打包的可能性。下面我们进行优雅改造,文中所用的是AGP7.0+,AGP7.0改动挺大,7.0以下的自己修改即可。
步骤2可以使用gradle提供的替换apisubstitute module(dependenceName) with project(":moduleName"),该api可以将原始依赖dependenceName(例如com.alibaba:fastjson,不包含版本号),替换成本地moduleName模块。 可以监听app模块下的gradle配置
1 2 3 4 5 configurations.all { config -> config.resolutionStrategy.dependencySubstitution { } }
这样就不用反复修改依赖了,但这样还不足够方便
优雅永不过时 在工程根目录下新增debug_aar.gradle脚本,脚本内容如下。(AS提示import com.alibaba.fastjson.JSONArray错误,实际上是成功导入的,知道怎么消除的留言)
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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 buildscript { repositories { maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public' } mavenCentral() } dependencies { classpath "com.alibaba:fastjson:1.2.76" } } import com.alibaba.fastjson.JSONArrayimport com.alibaba.fastjson.JSONObjectList<ModuleSource> list = loadDebugConfig() for (ModuleSource module : list) { if (module.debug) { include ":${module.moduleName}" project(":${module.moduleName}" ).projectDir = file("${module.sourceDir}" ) println("debug外部模块[:${module.moduleName}],源码路径 ${module.sourceDir}" ) } } if (list.size() > 0 ) { gradle.addProjectEvaluationListener(new ProjectEvaluationListener() { @Override void beforeEvaluate(Project projectObj) { } @Override void afterEvaluate(Project projectObj, ProjectState state) { projectObj.configurations.all { config -> config.resolutionStrategy.dependencySubstitution { for (ModuleSource ms : list) { if (ms.debug) { substitute module(ms.dependenceName) with project(":${ms.moduleName}" ) } } } } } }) } def loadDebugConfig() { List<ModuleSource> list = new ArrayList<>() String json = null try { json = file("debug_aar_config.json" ).getText() } catch (ignored) { println("根目录不存在debug_aar_config.json文件。(如果不需要debug aar源码忽略该信息)" ) } if (json == null ) { return list } JSONArray jsonArray = (JSONArray) JSONObject.parse(json) for (int i = 0 ; i < jsonArray.size(); i++) { JSONObject ob = (JSONObject) jsonArray.get(i) boolean isDebug = ob.getBoolean("debug" ) String moduleName = ob.getString("module_name" ) String sourceDir = ob.getString("source_dir" ) String dependenceName = ob.getString("dependence_name" ) if (moduleName == null || sourceDir == null || dependenceName == null ) { println("数据[${moduleName},${sourceDir},${dependenceName}]异常,该配置被忽略!!" ) continue } list.add(new ModuleSource(isDebug, moduleName, sourceDir, dependenceName)) } return list } class ModuleSource { boolean debug = false String moduleName = null String dependenceName = null String sourceDir = null ModuleSource(boolean debug, String moduleName, String sourceDir, String dependenceName) { this .debug = debug this .moduleName = moduleName this .dependenceName = dependenceName this .sourceDir = sourceDir } }
使用 在settings.gradle中引入上面的脚本,如下:
1 2 3 4 5 6 7 8 rootProject.name = "Test" include ':app' try { apply from: 'debug_aar.gradle' } catch (ignored) { }
让这个脚本工作起来还需要一个配置debug_aar_config.json文件,这个文件应该被加入到git忽略文件,如果不存在这个json文件,我们的脚本是不工作的,这样就不影响CI的正式发版。 在根目录下创建debug_aar_config.json文件,文件内容如下
1 2 3 4 5 6 7 8 [ { "debug" : true , "module_name" : "testModdule" , "source_dir" : "D:\xxx\test" , "dependence_name" : "com.alibaba:fastjson" } ]
debug:是否调试aar源码
module_name:调试源码时模块的名字
source_dir:源码路径,以根目录为起点的路径写法,所以一般需要用..返回到上级
dependence_name:aar的远程依赖 json是个数组,可以增加或者删除,每次修改完json文件,需要sync工程通知修改。
可以看到只需修改json即可。
注意事项
org.gradle.configureondemand=true的配置,会导致在调试aar源码时,找不到对应的module。所以需要关闭这个配置