前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从deep link到信息流广告,魔窗sdk的演变

从deep link到信息流广告,魔窗sdk的演变

作者头像
fengzhizi715
发布2018-08-24 17:03:33
1.4K0
发布2018-08-24 17:03:33
举报
文章被收录于专栏:Java与Android技术栈

从最初的移动端运营活动到深度链接(deep link),再到现在的移动端原生广告,魔窗sdk经历了多个版本的迭代之后,功能逐步完善,开始步入4.x版本的时代。

去年五月份的时候,我写过一篇文章《移动端SDK的优化之路》,现在回过头再来看看发现过去一年多的时间里我们又做了很多事情,所以有了新的一篇文章。

一. deep link

1.1 支持deep link和deferred deep link

早在2015年下半年就开始做deep link的功能,当时的版本已经支持了deep link以及deferred deep link(场景还原)的功能。

所谓deep link,是解决各个App之间信息孤岛的问题,实现App之间能够像网页一样能够自由跳转。

deferred deep link 是指用户打开一个h5页面的时候并没有安装对应的 app,在安装 app 以后可以直接通过 deep link 到 app 对应的内容。

场景还原.png

从后台的数据分析显示,大多数的客户对我们deferred deep link(场景还原)更感兴趣。为此,我们也一直在努力提高场景还原的匹配度。

1.2 为了能从微信朋友圈回流到App,Android版本使用应用宝跳转

iOS能够借助Universal Link从微信朋友圈跳转到App的具体页面,Android就没有这么幸运了,虽然谷歌早就提出了App Links但是国内很多手机并不支持,我们借助应用宝的链接来跳转到App的具体页面。

应用宝跳转原理跟 deferred deep link 是一样的,并不会100%的准确匹配,但绝大多数情况是可以成功跳转的。

1.3 iOS10之后,第一时间优化WebView的跳转

iOS 10之后,用户在WebView中使用uri scheme做应用间的跳转时,必须把目标App的uri scheme加到Info.plist中。

对于那些在 WebView 中使用魔窗的短链接客户而言,如果仅仅是做应用内的跳转,那是不需要把自己的Scheme放到Info.plist就可以直接调用。魔窗的短链会自动匹配操作系统版本和浏览器信息,在支持Universal Link的浏览器中自动使用Universal Link,如果不支持Universal Link的浏览器则用Scheme进行跳转。

1.4 去年11月初,sdk跟服务端通信的接口全面使用https

2016年的WWDC规定在2017.1.1之后iOS App必须全面支持https协议。我们在2016年10月的版本开始做支持https协议的功能,android 和 iOS两个平台的sdk都支持了https。赶在了11月初上线,给开发者留足时间,让他们替换新版本上架。

二. 原生广告

魔窗广告.png

我们的原生广告是基于魔窗位的,魔窗位可以埋在App的任意位置包括开机画面、Banner位、任意文字或图片的地方等等。

在新版本中,我们还新增了信息流广告。

三. 信息流广告

什么是信息流广告?不了解信息流广告的童鞋可以看我之前的文章《对信息流广告以及未来移动端广告的简单思考》

我们的sdk支持原生的信息流广告。提供原生的控件给到开发者,屏蔽了其中的技术细节,方便开发者直接使用到项目中(或者feed流中)。

信息流广告样式.jpg

原生控件能够给用户带来更好的体验,无缝地插入到App Native的页面中。除了原生控件之外,还支持将信息流广告的metadata返回给开发者,供开发者自行渲染。

信息流展示的策略,可以在后台进行配置。

信息流广告配置策略.JPG

四. sdk的设计原则和架构

4.1 模块化设计

从最初的所有代码都在一个主工程,到现在拆分成多个module,结构更加清晰。

按模块划分.jpeg

在下一个版本中,android 和 iOS 都会考虑将原生控件的功能拆分成一个单独的sdk。

4.2 面向对象的设计原则

在设计sdk时,我们一定会遵循面向对象的法则。

4.2.1 单一职责原则(Single responsibility principle)

单一职责原则是指:对一个类而言,应该仅有一个引起它变化的原因。简单来说,一个类中应该是一组相关性很高的函数、数据的封装。

sdk的网络框架并没有使用android 、iOS流行的okhttp、retrofit、AFNetworking等。因为需要考虑到sdk包大小的问题,我们使用对应操作系统底层的API来实现。因此,在android和iOS我们都做了一套简化的框架,大致流程是这样的:

http框架.png

我们遵循了单一职责原则,它主要由四个部分组成:Request、RequestQueue、NetworkExecutor和ResponseDelivery,每一个部分只负责自己的工作。

Request是各种请求类型。

RequestQueue是消息队列,维护了提交给网络框架的请求列表,并且根据相应的规则进行排序。

NetworkExecutor是网络的执行者,从消息队列中取出Request,请求完成之后将结果投递给UI线程。

最后,由ResponseDelivery来封装Response的投递,保证Response执行在UI线程。

4.2.2 接口隔离原则(Interface Segregation Principle)

接口隔离原则是指:建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。

为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。 在程序设计中,依赖几个专用的接口要比依赖一个综合的接口更灵活。接口是设计时对外部设定的“契约”,通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。

sdk中广告相关的类图.png

我们在处理广告时,对外只暴露AdManager类。广告展示类(AdDisplay)被AdManager所依赖,不对外开放。对于不同的广告,可以通过setAdStrategy()方法来设置不同的广告策略,进行广告展示。广告策略(AdStrategy)也是一个单独的接口。

4.2.3 迪米特法则(Law of Demeter)

迪米特法则又叫最少知道原则,一个类对自己依赖的类知道的越少越好。对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。

所以,sdk对外暴露出去的方法需要严格控制,只给开发者足够使用的API,无关的方法是不会开放出来。

4.2.4 常用的设计模式

除了上述原则之外,sdk还采用了多种设计模式,工厂和单例模式就不必说了,例如:

魔窗位或者广告位的点击,需要传递的参数众多,为了避免混淆这些参数采用了Builder模式。

sdk内部处理多种类型的广告时,对不同的广告需要使用不同的策略,因此采用了策略模式。

还有空对象模式,因为sdk内部的代码也存在着链式调用,如果链式调用出现了空指针那绝对是灾难,必然会导致App Crash。可以参考之前写的文章《为了程序的健壮性,我们可以使用空对象模式》

总之,在设计sdk时,尽量会采用符合高内聚、低耦合以及开闭的原则。

4.3 懂得取舍

处理取与舍是一个哲学的问题,能够不断地舍弃原先的代码的人,才能写出更好的代码。有人会说,那不就是重构吗?经常我们所舍弃的代码并不是不好,而不是最合适的解决方案。

曾经有一段时间我特别喜欢RxJava的风格,甚至考虑在sdk4.0中引入Rx的写法。在去年,我写了几个简单的操作符比如map、flatMap、forEach等来模拟RxJava的写法,并引入到sdk中使用,后来我理解了Java 8的lambda表达式以后,立刻明白完全没必要自己在sdk中写这些东西,果断删除相关的代码。

五. 测试

5.1 静态代码分析工具

sdk每一次发布之前,都需要先使用静态代码分析工具查找代码的缺陷。静态代码工具还能给出提示让开发者纠正不正确的写法。

在android平台上我们使用的工具有findbugs、pmd、checkstyle、facebook infer。

在iOS平台上我们使用Xcode自带的静态分析工具Analyze 和 facebook infer。

纠正完这些工具所提示的缺陷,才会交给测试进入下一轮的测试阶段。

quality.jpeg

5.2 内存泄漏分析

说实话,自从有客户给我们报sdk的内存泄漏bug之后,我们就特别重视这一块的问题。一方面,使用专业的工具来进行测试。目前在android平台使用的工具是LeakCanary,在iOS平台还是使用Analyze。另一方面,多做code review,基于经验来查找可能存在潜在的内存泄漏的地方。所以,sdk对每次开放出去的callback接口都会非常谨慎。

未来,在android版本的sdk中会考虑采用类似glide的方式,内部的Request可以随Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear,从而节约流量和内存,并且防止内存泄露。

5.3 后台收集sdk的bug

sdk遇到最大的困难可能不是来自功能上的,而是一个bug在我们这儿无法重现,但是在客户的手机上却能100%地稳定重现。

我曾经让平安wifi的研发同学寄出一台能够重现sdk bug的Android手机给到我们,我们debug并修复完之后,再寄还给他们。

除了这些,也经常会遇到一些奇奇怪怪无法想象的bug,比如之前《记录两个神奇的android bug》

虽然,sdk本身能够上报bug到后台,但是最初仅限于客户能够看到自己的app crash相关信息。作为sdk的开发者,我们也无法看到这些信息。后来,终于有了一个单独的系统能够专门过滤出属于魔窗sdk bug的信息,供sdk开发人员进行查询。每次发版前,我们都会先修复上一个版本存在的bug,然后交给测试。

六. 总结

本文是对将近两年来移动端sdk开发的小结,此过程可谓是踩坑无数,但是sdk的开发还要继续,未来也远远不止于移动端的原生广告,sdk还会提供更多的优质内容给到开发者。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.07.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. deep link
    • 1.1 支持deep link和deferred deep link
      • 1.2 为了能从微信朋友圈回流到App,Android版本使用应用宝跳转
        • 1.3 iOS10之后,第一时间优化WebView的跳转
          • 1.4 去年11月初,sdk跟服务端通信的接口全面使用https
          • 二. 原生广告
          • 三. 信息流广告
          • 四. sdk的设计原则和架构
            • 4.1 模块化设计
              • 4.2 面向对象的设计原则
                • 4.2.1 单一职责原则(Single responsibility principle)
                • 4.2.2 接口隔离原则(Interface Segregation Principle)
                • 4.2.3 迪米特法则(Law of Demeter)
                • 4.2.4 常用的设计模式
              • 4.3 懂得取舍
              • 五. 测试
                • 5.1 静态代码分析工具
                  • 5.2 内存泄漏分析
                    • 5.3 后台收集sdk的bug
                    • 六. 总结
                    相关产品与服务
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档