资讯专栏INFORMATION COLUMN

bye2018,hi2019

Dean / 3421人阅读

摘要:这里要颁发两个年度最佳应用一个是海外的,一个是酷狗音乐,它们暴露了两个很严重的平台漏洞。酷狗音乐遇到的问题。

辞旧迎新。

2018的工作总结一直拖着拖到现在忍不下去了终于扣了半天扣出一个总结。

2018年已经过去,回看,有努力,有成果,也有遗憾,有无奈。

由于不考虑kpi,所以主要总结遗憾和无奈。

最大的遗憾

是立了一个为听障/视障人士开发更满足他们需求的功能交互的flag,结果无疾而终。
目前苹果手机做的相对比较好,但是价格较贵,听视障碍人士很多收入不高,android手机价格相对便宜但是这方面做的不太好,第三方软件受限于权限问题,某些方面可能做不了系统厂家可以做的事。
原因有很多成分,自己努力坚持不够吧。

最大的无奈是

在软件供应链上被巨头鄙视了。
尽管做了很多努力,比如配套的生态,重点宣传等共赢措施。
原因有很多成分,也许是自身体量的问题,巨头看不上,也许是沟通问题,没找对门路或者没能打动对方。

没有bug的一年,不是完整的一年,2018年bug主要分布:

新需求产生的bug为33%。

也就是自己作出来的问题占了1/3。可以理解。
年度最作,录像防抖方案存在瑕疵,永远有20多帧视频cache在防抖模块里,只有在结束的时候才能flush出来,20多帧视频在时间维度上差不多要1秒钟了,在结束之前音频相应的就多了1秒钟,而从录像的框架和编码的实现上都不会在兼顾这种奇葩情况上浪费时间,所以录像播放的最后1秒只有声音没有视频观看体验很不好。
最终权衡再三妥协再三,最佳方案是,作了一个小模块cache音频1秒钟左右,结束的时候音频cache和视频cache默认被放弃,这样录出来的视频就非常同步了,虽然最后800毫秒左右会丢掉,这是综合最大效益的方案了,硬伤没办法。

传统框架上的问题为27%。

不到三分之一,比如解码,播放,交互等等。

声音和音质的问题占了15%。

包括测出来的和用户反馈的。
视频图像质量的问题报告或反馈几乎没有(彩条,绿屏,马赛克,不完整等属于视频图像解码显示问题不属于质量问题)。
有2个原因,用户对视频图像质量的变化不敏感或者不挑剔,或者用户群还没有形成这样的意识环境,视频图片行业内容为王,有的看就行还要啥自行车,还有就是视频行业的内容巨头们也是很关注视频的质量的体验的,当然他们也关心带宽,所以他们提供了有前提条件的内容质量,但是也不尽然,最近在重温西游记前半部分,无论哪个档次画面都让我觉得还不如我小时候看的crt画面清楚。
但是音质就不一样了,我们对声音更敏感和挑剔,一首3分钟的音乐,中间出现两次杂音或者卡顿之类的,就要骂娘了。
可能还有部分原因是用户没有画质反馈入口,这个可以完善。

CTS/GTS/VTS等问题占比11%。

这是google为了保证android开放生态下系统服务一致性安全性等方面的强制措施。
而且各种TS越来越多,收的越来越紧。好好搞,google会考试的,考不过后果很严重的,上个月的搞完了吗,这个月还有,忙起来,省的你们闲得想自己搞个操作系统。

性能,功耗,稳定性占比6%。

框架的性能,功耗在cpu一定的情况下80%是一定的,20%可能存在优化空间。业务上的功耗性能问题会比框架要多得多。
稳定性问题占了大部分,框架承上启下提供了一些服务,上层业务在框架上发展,框架的缺陷或底层缺陷导致的框架不可用或可用性变差,会表现在上层业务上,有些业务是系统业务会引发连串的系统问题导致系统不可用或可用性降低,用户体验变差,如果上层业务不受影响,谁管你框架的死活,当然这是不可能的,业务是鱼框架是水。

平台漏洞占比5%。

多带带拿出来是因为,这种坑太深太隐蔽,而且造成的后果比较严重。
几家平台坑的各有特点,某家最坑,使用这个平台的客户较少,不过代码最干净,研发投入最大。
这里要颁发两个年度最佳应用一个是海外的sweetsanp,一个是酷狗音乐,它们暴露了两个很严重的平台漏洞。
(1).sweetsnap遇到的问题。
是无法正常录像,框架层面也没有报告给app,app在这个过程中认为一切正常,调查发现sweetsnap在使用编码接口时,参数设置存在逻辑问题:它使用了b frame,但是b frame个数为0,而p frame的个数大于0。
首先,这样设置在编码原理上是有问题的,但是mediacodec api并没有显示的限制这种设置或者说明,那样的话增加了接口的复杂度,对开发者是不友好的,边界的检查放在了框架设置更底层的hal层,然后把结果逐层上报。
这里平台上v4l2边界检查的逻辑出现了漏洞,放过了使用b frame,但是b frame为0, p frame不为0的情况,没有正确上报问题,实际编码又没有成功。
(2).酷狗音乐遇到的问题。
是功耗比正常数据大了300多mA。
看systrace统计,audiotrack中的一个线程占有cpu时间异常,感觉在空跑。
发现是mMyCond.waitRelative(lock, paused_ns)这个函数实效,进一步调查发现这个函数在应用处于32bit运行时失效,基本所有音视频第三方应用都是32bit运行时,都采用audiotrack输出声音,所有基本都有这个问题。
用我们可以切换32/64bit运行时的demo发现,在32bit下也是这种失效情况,64bit下函数有效,由于参数paused_ns数值比较大,加上32bit/64bit的差异,怀疑是溢出问题。
最后发现waitRelative最终实现是libc的__pthread_cond_waittimeout函数,超时参数在32bit下CLOCK设置为REALTIME时,会发生溢出,需要将CLOCK调整为MONOTONIC。

开发者提出的问题占比在3%。

但有一部分问题系统层面也不好处理或者没有义务处理需要开发者自己关注注意api的使用。
一些api使用开发者很熟悉了比如bitmap用完要记得recycle,culsor要记得close之类的,网上类似的文章也一大堆,但是有些api或参数的使用注意事项几乎没有介绍。
(1).对于没有正确使用api的android设计了一些惩罚机制。
应用开发者应该很清楚exception这个机制。
在 android除了exception机制之外其实还有其他提醒开发者的方式,比如assert, abort等,但是它们不像exception这么温柔了,直接用自杀的方式告诉你兄弟这样搞不对。
比如app要录像,录屏的时候,分辨率宽高最好设置成2的倍数,也就是不要出现奇数,16的倍数最好,方便底层编码工作,有些平台对不是2的倍数的情况,会直接在native层abort导致程序异常。
而如果对多媒体视频不太了解的java工程师往往比较迷惑暂时找不到头绪。即使看到native fatal backtrace。
即使在webrtc这样非常流行的开源库里,在一个动态分辨率的调整的模块里也存在类似问题,它降低分辨率的算法是直接宽高各处以2,这样降低分辨率的梯度不够平滑不说,如果分辨率处以2最后会变成奇数,造成兼容性问题。
(2).还有一种应用更过分,占着所有坑,别人来了没坑用。
(2.1).比如有些开发者,在自己的应用里,无限制的使用mediaplayer但短期内不释放,用了几个发现用不了。
这是因为mediaplayer为开发者提供播放便利的同时,它也隐藏了很多细节比如解析解码等模块或资源的管理。
一个mediaplayer对象的创建或使用就代表了一套解析解码等相关资源的分配,只有这个mediaplayer被释放了(不一定java对象被回收),这套资源才会回收释放,这也是mediaplayer提供release这个接口的设计初衷,让开发者尽早释放配套资源,可以在java对象被回收之前。
如果这些配套资源都是软件的,在内存允许的情况下,理论上是不存在对象个数限制的,但是解码器有些是硬件的尤其常用的h264,h265等,硬件资源是有限制的,管理解码器的框架叫omx,硬件解码器omx实例的个数是有限的。
对于h264等格式android播放框架默认优先使用硬件解码,一个mediaplayer对象分配一个硬件解码器omx实例,但是有个数限制,超过个数分配不出来。
而android框架上并没有硬件分配不出来转去分配软解码器的设计(如果这么做会产生另外一个困惑,开发者不知道你第n个解码器是软的还是硬的)。
硬件解码器omx实例个数每个平台不一样最少的也有2个,最多的可能有8个,同时播放2个视频够了吧(2个mediaplayer对象),如果真有特殊需求,就不要用mediaplayer了,用android的mediaextractor,mediacodec去同时调用硬件和软件解码器,或者自己用ffmpeg实现解码播放。
(2.2).除了占着mediaplayer不放的,还有占着audiotrack不放的。
而且是某些日活上亿超级应用,用户每天都会打开。
有些定制系统为了用户体验追求快速启动,会把一些超级应用放进一个名单里,不会被真正杀死。
audiotrack也是有限的,最多32个,如果被超级应用全部吃掉,不释放或泄漏了,其他有音频输出需求的应用再也获取不到audiotrack实例,用户就听不到声音了,而且用户杀死也没用,因为它没被真正杀死。

my chaos monkey design
what is chaos monkey?

名字来源于netflix的一个开源项目chaos monkey,该项目故意制造一些线上问题然后看整个系统包括软件,人员等的反应能力。逆向思维,值得学习。
在这里是一套自动化测试体系,包含了对边界条件,性能,重点api等扫描的测试用例和自动化过程实现。是对android官方提供的资源的一个补充。

buster。

灵感也来源于netflix的chaos monkey。
在移动端实际工作中,经常会遇到一些逼近或突破软件系统极限的问题,对软件的边界设计是一个考验,也会暴露很多问题。
这些问题,散落在各个模块的bug系统里,即使有关注也是各个模块人工跟踪可重复性差,并没有作为一类问题加以重视。buster做的是,将这些问题作为一类问题,并且利用自动化的方式实现高可重复性,提高扫描或回归等测试效率。
比如,一张巨大的图片,应用在前台解码时几乎会耗尽所有的内存,系统剩余可用内存会逼近0。
这个时候会发生一些不可以预期的严重问题,也许是前台应用会崩溃界面闪退,也许是其它模块内存得不到分配导致系统卡死等等。
现实的场景有很多,比如微信朋友圈发图选图的时候打不开或闪退,文档或图库等闪退或导致系统卡死等等,这些地方都会去解码图片,如果解码列表里有一张巨大的图片就会发生这些问题。

chanpion。

关注框架重点api的性能,核心是它的benchmarks,这些数据是通过对比不同平台,厂家,机型的出来的。
属于同一代的平台会拿来进行比较,但是也要注意测试时,同一代的平台不同厂家产品,运行时的当前cpu频率,比如都是660的平台,同一测试场景结果差异比较大,要关注下当前cpu频率是否有差别,有些厂家会通过调频做一些加速。
还有一个方法确定,就是把执行过程拆分成一个个原子步骤,每一步耗时,在总耗时少和总耗时多的产品上都统计出来,如果每一原子步骤耗时都没有异常大的说明你的这个过程问题不大,差异应该在不同产品cpu频率不同,反之如果在耗时多的产品上执行过程中某一原子步耗时过长,这里可能存在问题需要优化。

straight。

是api的demo实现,便于问题的验证和对比,也可以给开发者作为参考。
主要是场景和feature demo,更贴近于实际问题,是对android api demo的一个补充。
比如,通过实现多路录音,来模拟录音的同时录像,voip通话之类的场景。

展望2019

less is more & slow down。
一个词概括就是focus,在有限资源的前提下,专注1,2件最有价值最有意义的事情。
2019我们还有机会吗,试过才知道。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14666.html

相关文章

  • JavaScript — Null vs. Undefined

    JavaScript — Null vs. Undefined 初学者往往搞不清楚null和undefined的区别,本文深入剖析null和undefined的异同。 null是啥? 关于null有两点需要掌握: null是一个空值 null是被赋值来的 下面是个 Demo, 我们给 a 变量赋值为 null: let a = null; console.log(a); // null ...

    tanglijun 评论0 收藏0
  • Spring AOP的实现机制

    摘要:本文主要介绍的两种代理实现机制,动态代理和动态代理。直接使用首先定义需要切入的接口和实现。我实现了一个工厂类来获取代理对象代理具体使用输出结果动态代理我们再新建一个来,这次不实现任何接口。 AOP(Aspect Orient Programming),一般称为面向切面编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。AOP实现的关键在...

    dendoink 评论0 收藏0
  • JS常用正则表达式备忘录

    摘要:想阅读更多优质文章请猛戳博客一年百来篇优质文章等着你正则表达式或用于匹配字符串的各个部分下面是我创建正则表达式的备忘单。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 正则表达式或regex用于匹配字符串的各个部分 下面是我创建正则表达式的备忘单。 匹配正则 使用 .test() 方法 let testString = My test string; let t...

    reclay 评论0 收藏0
  • 数组、伪数组、字符串、对象常用api大聚会

    摘要:数组改变数组的不改变原数组返回新数组没有毛线一数组字符串将数组转成字符串可自定义分隔符没有毛线将数组转成字符串并分隔每个元素没有毛线没有毛线拍照返回字符串没有毛线二数组元素添加向数组尾部添加元素改变了数组添加一个没有毛线添加一个向数组头部添 数组api 改变数组的 push、pop、unshift、shift,sort、reverse、splice不改变原数组 返回新数组 concat...

    haobowd 评论0 收藏0
  • ES6+好用的小技巧,让你的代码更干净,短巧,易读

    摘要:模板字符串扩展操作符操作符,有两个主要用处复制一个新的数组或对象把多个参数赋值给一个数组变量把一个数组变量赋值给多个参数是一个新的数组,内容和一样合并对象属性,后边的属性会覆盖前边的,可用于修改对象的某个属性值输出默认参数给方法添加默认参 模板字符串 let name = siri, age = 18, job = front-end engineer let oldStr = Hi,...

    sanyang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<