暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

广告模块化设计与实现

AggrxTech 2021-11-02
1356

前言

随着APP需求的不断迭代和团队人员规模的增加,代码的坏味道越来越多,编译时长变长、代码冲突增加、新需求的工期变长。面对这些问题模块化拆分是一个好的解决思路。合理的模块化拆分可以降低代码的耦合度,方便单个模块的调试、升级、测试等。本文将对Android模块化拆分做一个探索。

目标


  • 宿主:不做具体的功能实现,只负责组合业务模块,组装成一个完成的APP,即可以实现一套代码生成多APP

  • 业务模块:将项目拆分成一个一个独立的module,可独立运行

  • 基础组件层:与业务无关、与项目无关,所有项目都可以复用,包含各种开源库以及与业务无关的自研库

优点

  • 架构灵活,焦点分离

  • 耦合低,模块间可自由组合、分解

  • 方便单个模块功能调试、升级、测试,提高开发效率

  • 多人协作只负责单独模块,互不干扰

模块化实战-广告模块化拆分

现状

  • 三个联运包:oppo、huawei、xiaomi

  • 七家广告sdk:广点通、头条、快手、百度、oppo、小米、华为

  • 16个广告位

  • 联运包通过分支开发方式,每次发版前需要合并代码

目标

  • 一份代码生成三个联运包和普通包

  • 广告位广告提供者全支持,例如目前书架只支持广点通原生广告,改造后后台可随意配置广告提供商,客户端皆可支持

  • 新广告sdk的极速接入

实现方案

  • 广告流程接口化

  • ARouter动态发现广告实现

广告流程


广告流程接口化

所有广告的加载流程都一致,将流程抽象到抽象类AdBaseImpl中,具体的广告sdk实现AdBaseImpl

ARouter动态发现广告实现

拆分各个广告的module,module中包括广告的aar、不同广告类型的实现类(继承AdBaseImpl),module只对外提供一个ARouter的IAdInitProvider,在IAdInitProvider中初始化相应的广告sdk,并将实现类注册到AdFactory


普通包不依赖oppo、华为、小米的module,所以普通包apk ARouter init时是不能发现oppo、华为、小米的广告实现。


oppo联运包不依赖华为、小米的module,所以普通包apk ARouter init时是能发现oppo的广告实现,但是不能发现华为、小米的广告实现。



所有广告位可以根据providerId获取到具体的广告实现类,根据AdBaseImpl的流程填充广告

接入文档

  1. 新建module,添加广告的aar等;

  2. module的build.gradle中,使用implementation方式依赖aar,保证app中不会引用到aar中的代码;ARouter相关配置;依赖 base module

  3. module中build.gradle 

  4. 实现AdBaseImpl

  5. 实现IAdInitProvider接口,在ARouterConstant中定义ARouter的path,path的规范是/moduleName/(provider/activity/service)/业务/功能,例如/baiduAd/provider/ad/init

  6. IAdInitProvider#initAdSAdk()中初始化sdk,也可以在使用的时候再延迟初始化;调用AdFactory.registerAdInterface注册广告的实现类

  7. AdFactory的sInitPaths增加这个path

  8. 只有IAdInitProvider的实现类是public的,其他类都设置为包内可见,防止app中误用

踩坑之旅

  • ARouter初始化路由映射表的流程,如下图,
    如果是debug或版本更新时重新扫描dex文件获取对应的路由文件,否则会从SharedPreferences缓存中获取路由路由文件 

代码本身没有问题,这样做可以加快初始化速度。
但对于版本号相同的不同的联运包之间相互覆盖却会出现ClassNotFound问题,不同联运包的代码是不相同的。

  • 问题解决方案:
    通过arouter-register实现。Arouter自动加载路由表的插件是使用的通过gradle插桩技术在编译期插入代码来达到自动加载路由表信息,保证了路由表和代码的一致性。

  • 接入步骤


    • app的build.gradle中增加 apply plugin: 'com.alibaba.arouter'

    • 根目录的build.gradle dependencies 中增加classpath "com.alibaba:arouter-register:$arouter_register_version"。arouter_register_version表示最新的arouter-register版本

    • 编译后LogisticsCenter#loadRouterMap会注册所有的路由信息


文章转载自AggrxTech,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论