前言
起初,在接到广告方面的需求时,只是实现一个广告平台的广告接入并没有多少复杂的逻辑,所以按照官方的文档按部就班的接入就可以了。但随着时间推移业务增长单一广告已不能满足现有的需求。对于广告业务提出了更复杂的要求。不仅要实现多种形式的广告接入,还要实现不同广告平台的对接,以及后期需要对广告平台进行灵活的添加与删除,最后需要单独成一个广告模块。首先我想到的是我要开发一个类似于友盟分享一样的聚合功能模块,基于这样的前提我开始了对于广告模块的设计开发。整个过程大概分为三个阶段:代码封装;提取为功能模块;组件化并生成远程依赖。
代码结构重新设计——代码封装
首先,我对比需对比所有广告平台的广告接入流程发现大都分为几步,初始化广告sdk——传入对应广告位id拉取广告——返回结果,总结了一下初始化方式以及所有平台的广告类型大体相似,返回结果分为数据与View两种形式。根据现有需求与广告sdk的加载过程大体总结出了广告聚合功能需要的几个重要步骤,初始化——拉取广告展示配置——根据配置拉取对应广告数据——根据广告数据生成广告View——返回View展示广告。根据上面流程可总结出主要需要下面几个类:类关系图1-1
AdManagerHolder:对外暴露的广告接口,主要功能接收外部参数,协调各广告平台管理类中的具体功能调用,包括初始化,各广告位展示接口,拉取广告配置信息,超时控制,生命周期同步。
IAdvertManager:此接口实现类为各广告平台的管理类,主要功能包括对应广告平台的初始化——广告拉取——广告缓存——广告结果返回。包括了不同生命周期时的广告处理。
IAdvertView & IAdvertSplashView:这两个接口的实现类主要是实现数据的处理组装成View
基于以上代码结构把广告功能相关代码封装并使代码耦合度降低,方便以后的模块化组件化。
创建module——提取为独立模块
提到功能模块化我首先想到是创建新的module,使功能可以不依赖主项目中的相关资源而可以实现自给自足,并且可以方便插拔。那么要实现这样一个结果,那么必然所有广告相关的代码,依赖,资源文件,menifest中的配置信息都尽量从主项目中拆分出来。具体的代码逻辑不再赘述,下面给出大概拆出来的对应代码及资源文件。如图2-1
注:拆分成独立module后广告功能中会需要一些请求地址或者其它一些主项目相关的参数,可以通过初始化接口统一传入。这样做的原因是为了可以在其它项目中更方便依赖使用广告模块。
aar的打包上传与引用——组件化的最终实现
要实现组件化首先了解一下组件化的基本概念,很多人对于模块化与组件化概念模糊,网上找了一些概括的比较好的定义:组件化是建立在模块化思想上的一次演进,一个变种。组件化本来就是模块化的概念。但是组件化的核心是角色的转换。 在打包时, 是library; 在调试时, 是application。根据这个概念再去看一些组件化的相关资料,然后结合公司项目中的实际情况瞬间了然。那么接下来的组件化的过程也有了一个大概的思路。我所要实现的组件化要符合几点要求:可打aar包、可上传aar到私服、支持依赖module与aar远程依赖切换。为达到以上要求我需要对项目做以下改造。
1.新建一个项目引入广告module依赖。(为了方便我直接复制了一份主项目进行修改)
2.支持打包lib文件夹中的第三方aar到新的aar中。
实现这个功能需要接入第三方的插件fat-aar-android。
https://github.com/kezong/fat-aar-android
基本原理是把第三方的aar文件解压并把其中的代码、资源与menifest文件等合并然后打包生成一个新的aar文件。
具体原理请参考:https://www.jianshu.com/p/8f7e32015836
3.支持上传aar到私服
上传aar到私服需要配置gradle相关代码。如图3-1
4.配置私服依赖并加入module模式与远程依赖模式切换
远程依赖地址配置如图在根目录中的build.gradle中配置如图3-2、3-3
module模式转换配置方式为gradle.properties文件中加入isModule=true
主项目中配置
if(isModule.toBoolean()){
implementation project(':kkadvertise')
}else {
implementation'com.weshine.kkadvertise:kkadvertise:0.1.0@aar'
}
注:当项目打包aar时lib文件中有第三方aar文件上传私服远程依赖后会出现无法拉取到第三方aar问题,并报异常无法找到groupId。解决方法:找到对应第三方aar的包名并在build.gradle依赖中填写好group。图3-4
遇到的其它问题:
1.因为广告功能现在是以aar的远程依赖形式提供给其它项目使用所以为了方便依赖之后锁定问题,需要在项目中加入debug模式来控制是否打印日志。
2.组件化不可避免会涉及到混淆的问题,现在比较成熟的方案是把所有混淆都写在主项目中。我们自己打包的aar在主项目中也需要加入对应的混淆配置。