博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
考虑android library+flutter module怎么生成aar
阅读量:7171 次
发布时间:2019-06-29

本文共 5768 字,大约阅读时间需要 19 分钟。

简单介绍

开始学习flutter之后比较关注的实际问题之一就是怎么混合开发,今天主要思考一下Android项目中native(android library)+flutter以什么形式进行混合开发以及怎么生成aar的问题。以下的总结是我的拙见,在这里也是想确认大家是否也遇到了相同的问题,有不对的欢迎批评指教~~

大致的混合开发形式以及遇到的问题为:

1、使用官方的flutter module形式,依据官方给出的集成方案。

该方案中当native项目为android library时打包aar可能会存在一些问题。由于android library打包成的aar并不会包含其依赖的aar或module的内容,所以此时native项目生成的aar并不会包含flutter module中的内容,flutter module需要单独再打一个aar出来给调用方。

2、方案1存在的问题为aar文件本身不包含依赖传递的信息,很简单想到借助于maven pom传递依赖,即形成第2种方案;flutter module项目单独生成aar,上传至maven远程或本地仓库,在android library项目中通过仓库获取该aar,同样android library生成的aar也会上传到仓库,调用方通过仓库获取,所有依赖关系都会跟随pom文件进行传递。

该方案可能存在的问题为: 1)官方推荐的flutter module的目录结构为.android、.ios、lib,而且其中.android和.ios目录在.gitignore中,即不推荐上传module中的native项目(其他人从git clone该项目之后,通过执行flutter packages get即可自动生成.android、.ios目录),则不推荐在.android中添加业务代码或者自定义操作,那么就不方便执行flutter module的aar自动生成以及上传; 2)android library通过aar依赖flutter module不便于开发时的测试。

3、第三种方案为不使用官方推荐的flutter module形式,将dart代码,native项目组合为一个工程,类似于Flutter Application结构,只是native项目不是com.android.application,而是com.android.library。

该方案不存在flutter module怎么被依赖的问题,只需要在android library项目中生成aar即可。

选择方案

个人理解看下来可能第3种方案比较方便,但是如果想使用官方flutter module形式且开发方便,倾向于选择第一种方案:即通过官方集成方案将android library依赖于flutter module。

所以需要试图解决方案1存在的问题,实现android library项目生成的aar能包含其依赖的flutter module的内容。

解决问题

一开始解决问题的目标定为合并多个aar,github上也有生成fat-aar的解决方案。但是由于目前flutter module只包含自动生成的android原生代码,没有资源文件(如下第一张图),并且flutter module生成的aar(结构如下第二张图)中比较重要的几部分为asssets、libs、jni、classes.jar,所以可以预想将问题简化为:android library项目生成的aar只需要包含上面这几部分或许就ok了,先忽略manifest、res等的合并。

确定了解决方案之后,就开始分以下几点开始试验:

1、集成flutter module的assets

从flutter.gradle文件中可得知,assets目录中内容的生成主要依靠task依赖执行:

Task mergeAssets = project.tasks.findByPath(":${mainModuleName}:merge${variant.name.capitalize()}Assets")if (mergeAssets){                  mergeAssets.dependsOn(copyFlutterAssetsTask)}复制代码

其中copyFlutterAssetsTask还会依赖于其他flutter task,执行flutter build操作;所需要的assets文件最后都会被放入build/intermediates/library_assets/${buildType}/package${buildTypeCapitalize()}Assets/out目录中,其中buildType即为debug或者release或其他。

所以为了合并assets需要完成如下两件事情:

1)在android library中执行assemble操作时需要能执行flutter module的copyFlutterAssetsTask任务; 解决方案为在android library的build.gradle中添加如下内容:

def flutterProject = project.rootProject.findProject(":flutter")    flutterProject.afterEvaluate {        flutterProject.android.libraryVariants.all {            variant ->                if (variant.name == 'debug' || variant.name == 'release') {                    project.tasks.findByName("package${variant.name.capitalize()}Assets").dependsOn flutterProject.tasks.findByName("copyFlutterAssets${variant.name.capitalize()}")                }        }    }复制代码

同时要在android library的root project的build.gradle中添加如下配置,其中'mylibrary'为android library的module name;目前不是很清楚不增加为什么无法执行上面配置的flutterProject.afterEvaluate,所以这一点还需要优化:

ext { mainModuleName = 'mylibrary' }复制代码

2)需要能将上面flutter module的assets out目录添加为android library的assets目录;

if (variant.name == 'release') {android.sourceSets.release.assets.srcDirs += flutterProject.getBuildDir().getAbsolutePath() + "/intermediates/library_assets/${variant.name}/package${variant.name.capitalize()}Assets/out"} else if (variant.name == 'debug') {android.sourceSets.debug.assets.srcDirs += flutterProject.getBuildDir().getAbsolutePath() + "/intermediates/library_assets/${variant.name}/package${variant.name.capitalize()}Assets/out"}复制代码

2、集成flutter module的libs和jni

flutter.gradle中的task会将flutter sdk中的flutter.jar以及相关的so文件自动添加为flutter module的依赖,具体内容如下:

private void addFlutterJarApiDependency(Project project, buildType, Task flutterX86JarTask) {        project.dependencies {            String configuration;            if (project.getConfigurations().findByName("api")) {                configuration = buildType.name + "Api";            } else {                configuration = buildType.name + "Compile";            }            add(configuration, project.files {                String buildMode = buildModeFor(buildType)                if (buildMode == "debug") {                    [flutterX86JarTask, debugFlutterJar]                } else if (buildMode == "profile") {                    profileFlutterJar                } else if (buildMode == "dynamicProfile") {                    dynamicProfileFlutterJar                } else if (buildMode == "dynamicRelease") {                    dynamicReleaseFlutterJar                } else {                    releaseFlutterJar                }            })        }    }复制代码

这一点的解决方案即为将这些依赖添加为android library的依赖,具体做法为在android library的build.gradle中添加如下内容:

flutterProject.configurations.each {            conf ->                conf.getDependencies().each {                    dep ->                        if (dep instanceof org.gradle.api.artifacts.FileCollectionDependency) {                            org.gradle.api.file.FileCollection fileCollection = dep.getFiles().filter { file -> file.getName().contains("flutter") }                            if (!fileCollection.isEmpty()) {                                if (project.configurations.contains(conf)) {                                    project.dependencies { add(conf.getName(), dep) }                                }                            }                        }                }        }复制代码

3、集成classes.jar里面的内容

这一点也比较简单,因为flutter module里面java代码作为android library的源码,具体做法为

android.sourceSets.main.java.srcDirs += flutterProject.getProjectDir().getAbsolutePath() + "/src/main/java"复制代码

经过以上几点的集成,android library中assembleRelease或者assembleDebug生成的aar就会包含flutter module中几大重要的内容,然后将此aar放在另一个android application中引用,也可以正常调起flutter module中的flutter页面,说明集成成功。当然如果以后flutter module在资源、manifest清单文件中有更多重要的内容,则需要考虑这些内容的合并,就会比较复杂。

目前的实现方案比较简单,希望大家一起讨论一下是否可选第1种方案进行混合开发、其存在的问题是否需要解决以及大家一般怎么解决(我不希望自己又走到了某种歪门邪道。。。)~~;当然如果本文的方案值得使用,后续还会继续进行优化。

转载于:https://juejin.im/post/5caecd4af265da038d0b30c7

你可能感兴趣的文章
7年苦心钻研自动驾驶,最终Alphabet选择削减投入
查看>>
农民伯伯的福利到了,AR技术让种地更加easy
查看>>
4年后,nuTonomy要在10城市运行无人驾驶车
查看>>
李开复预言:人工智能将在10年后让50%的人失业
查看>>
iStaing获500万美元投资,VR室内设计离我们还远吗?
查看>>
EventBus与RxJava
查看>>
JFinal结合Sigar、echarts实现后台服务器监控
查看>>
SAP Netweaver和Hybris的数据库层
查看>>
编写安全 PHP 应用程序的七个习惯
查看>>
Elasticsearch 公司上市,市值近 50 亿美元
查看>>
如何正确看待量子计算的突破?
查看>>
从数据竞赛到专业第三方数据平台,科赛是如何高效提升「数据工作者」价值的?...
查看>>
IPerf——网络测试工具介绍与源码解析(1)
查看>>
ABAP Netweaver和git的快捷方式
查看>>
Java高级之内存模型分析
查看>>
Java日志框架-Spring中使用Logback(Spring/Spring MVC)
查看>>
蚂蚁金服战略投资ofo,双方合作进一步推进
查看>>
西咸新区“硬科技号”地铁专列上线运行,感受大西安的硬科技特色
查看>>
人工智能带来的社会影响
查看>>
袁煜明:现阶段区块链发展的最大问题是公链的不成熟
查看>>