美文网首页
YDL Android 组件化实践与拓展(3) - 马甲包自动化

YDL Android 组件化实践与拓展(3) - 马甲包自动化

作者: 孔睿 | 来源:发表于2020-04-28 18:54 被阅读0次

概述

概念

马甲包:和主产品包拥有同样的内容和功能,除了icon和应用名称不能完全一致,其他基本一致。

主包:主APP

马甲包的好处:

  • 占领搜索资源位,获取更多业务资源;
  • 为主包引流,提高主包品牌影响力;
  • 规避风险,预防万一。就像哔哩哔哩一样。哔哩哔哩刚下架了,他的马甲立马就顶上了。

存在问题

雷同问题

页面不可完全雷同,需要修改页面色调、主图、模块、样式。

长期维护

马甲是需要长期维护。如果一个马甲做得很好,那么完全可以将其独立出来作为精品马甲,其实就是独立APP,必要的时候,如果主包遭遇不测可以将马甲作为新的主包顶上。

方案

需要解决的问题
  • 使用新的icon、包名、应用名
  • 页面样式避免与主包完全雷同
  • 尽可能更多的复用现有代码逻辑
  • 后期维护起来不可成本太高
解决思路
  • 应用基础信息可配置化
  • 应用页面样式可动态设置
  • 根据配置信息依赖指定业务组件
  • 拆分壳应用与马甲包lib,创建脚本自动更新马甲包lib

实践

马甲包脚手架

脚手架

前端概念

​ 随着前端工程化的概念越来越深入人心,脚手架的出现就是为减少重复性工作而引入的命令行工具,摆脱ctrl + c, ctrl + v,此话zenjiang? 现在新建一个前端项目,已经不是在html头部引入css,尾部引入js那么简单的事了,css都是采用Sass或则Less编写,在js中引入,然后动态构建注入到html中;除了学习基本的js,css语法和热门框架,还需要学习构建工具webpack,babel这些怎么配置,怎么起前端服务,怎么热更新;为了在编写过程中让编辑器帮我们查错以及更加规范,我们还需要引入ESlint;甚至,有些项目还需要引入单元测试(Jest)。对于一个更入门的人来说,这无疑会让人望而却步。而前端脚手架的出现,就让事情简单化。

一键命令,新建一个工程,再执行两个npm命令,跑起一个项目。在入门时,无需关注配置什么的,只需要开心的写代码;另外,对于很多系统,他们的页面相似度非常高,所以就可以基于一套模板来搭建,虽然是不同的人开发,但用脚手架来搭建,相同的项目结构与代码书写规范,是很利于项目的后期维护的;以上就是为什么脚手架存在的意义, 让项目从"搭建-开发-部署"更加快速以及规范 (出自于某乎达人)。

项目说明

只需运行命令行输入Android 基础项目信息如应用名、版本号、包名

即可收获一个可以直接运行的定制化Android项目

脚手架环境
  • node: v9.2.0

命令

init | generate vest template.
  • 引入inquirer.js 交互式命令行工具,定义 question
  • 接收输入信息
  • 拉取模板项目
  • 写入输入信息
  • 提示帮助

核心代码

function create() {
    inquirer.prompt(questions).then(function(answers) {
        let _answers = JSON.parse(JSON.stringify(answers))
        let { name,  version, applicationID} = _answers
        const spinner = ora('downloading template'),
            tmp = path.resolve(process.cwd(), name)
                ...
        spinner.start();
        if (exists(tmp)) rm(tmp);
        download(`http://xxx/vest-template`, tmp, { clone: true } ,function(err) {
            spinner.stop()

            if (err) logger.fatal('Failed to download repo ' + TEMPLATE + ': ' + err.message.trim())
                    ...
          changeFile(tmp + '/config/vest.app.js', `${TEMPLATE}-name`, name)
          ...
        })
    });
};

使用示例

image
sync | sync vest project config
  • 使用fs读取项目配置文件自定义信息,包括:
    • 目标业务组件
    • 应用样式
    • 应用图标
    • 三方SDK配置信息
  • 写入自定义配置信息至Android项目

核心代码

 let thirdSdkArr = new Array();
    thirdSdkArr.push(thirdSdkPrefix)
    thirdSdkArr.push("APPLICATIONID=" + vestApp.applicationId)
    thirdSdkArr.push("APP_NAME=" + vestApp.appName)
    thirdSdkArr.push("VERSIONNAME=" + vestApp.version)
    thirdSdkArr.push("APP_FFROM=" + vestApp.ffrom)
    Object.keys(compileThirdSdk).forEach(function (key) {
        thirdSdkArr.push(key + "=" + compileThirdSdk[key])
    });
    thirdSdkArr.push(thirdSdkEndfix)
    let thirdSdkStr = thirdSdkArr.join("\n");
    let sdkPreIndex = propertiesContent.lastIndexOf(thirdSdkPrefix)
    let sdkEndIndex = propertiesContent.lastIndexOf(thirdSdkEndfix) + thirdSdkPrefix.length - 1;
    let sdkEndStr = (propertiesContent.slice(sdkEndIndex, propertiesContent.length).length !== 0 ? "\n" + propertiesContent.slice(sdkEndIndex, propertiesContent.length) : "")

    fs.writeFileSync(propertiesPath, propertiesContent.slice(0, sdkPreIndex).concat(thirdSdkStr, sdkEndStr), 'utf8');

使用示例

sync 使用示例

模板项目

项目目录

image

实现

  • 脚手架合并项目配置信息后写入vest.properties文件

  • 编写 build.gradle 脚本

    • 读取vest.properties

    • 写入配置信息至buildConfigField中

      new HashMap<String, String>((Map) vestProperties).each {
                  buildConfigField "String",it.key, "\"${it.value}\""
              }
      
    • 写入配置信息至manifestPlaceholders中

      manifestPlaceholders = new HashMap<String, String>((Map) vestProperties)
      
  • 脚手架读取vest.modules.js,写入modules.json文件至Android 项目下的app/src/main/assets目录下

  • 应用开启时,读取assets目录下modules.json文件,序列化为实例对象

     fun init(context: Context) {
            val assertsFile = getAssertsFile(context, "modules.json")
            if (assertsFile == null) {
                LogUtil.e("请先运行 vest sync 命令初始化配置文件")
                return
            }
            val configJson = String(assertsFile)
            if (TextUtils.isEmpty(configJson)) {
                LogUtil.e("请先运行 vest sync 命令初始化配置文件")
                return
            }
    
            modulesConfigBean = GsonProvider.getGson().fromJson(configJson, ModulesConfigBean::class.java)
        }
    
  • 使用配置信息实例对象初始化应用

总结

本马甲包自动组装方案使用配置文件和脚手架相配合,屏蔽Android项目信息,使其在使用时只需配置完成后运行脚手架命令就可得到定制化的Android项目。

后期添加管理后台,部署至服务器上后开发阶段可以完全不需要Android开发人员介入,只需定期更新版本。

极大减少Android开发工程师工作量,降低应用开发成本,解决了后期迭代更新不及时的问题。

相关文章

网友评论

      本文标题:YDL Android 组件化实践与拓展(3) - 马甲包自动化

      本文链接:https://www.haomeiwen.com/subject/wtmbwhtx.html