打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
简寻Android沙龙速记——张旭篇
张旭:大家好!今天我做的这场分享是技术分享,可能也想跟大家交流一下,我们在做一款Android应用过程中间经验和技巧,当然之前我也想小小介绍一下,我来自APUS,简单介绍一下APUS是谁?
我们公司主要做一个海外公司,我们99.99%用户都在海外,我们在国内平时很少做传播,可能听说人不多。我大概说一下我们公司做什么?首先名字介绍一下,我们公司很年轻,我们公司是2014年6月份筹建,到7月份才成立,当时几个创始人商量该起什么名字的时候?我们想APUS,为什么起这个名字?有几层意思,第一是南半球唯一没有神话的星座,就是天年座,我们想比较好将来神话我们自己撰写,第二的飞的最快的鸟,俯冲速度达到400公里/小时,希望我们公司发展很快、产品运行很快所以用这个鸟的名字,第三在法语是酋长的意思,最后起APUS。其实更重要的含义我们做产品缩写就是APUS,我们做的完美的用户系统。
我们公司主要做海外,目前估值已经超过15亿美金,一共拿了两轮投资,一共拿了1.16亿美金投资,在全世界已经有9.2亿用户,在全世界用户群规模只能算小小一步,全世界有60亿人口,差不多有30亿智能机用户市场,我们用了不到两年做到这样规模,也确实是全世界发展最快的互联网公司。去年我们也被Google Play评价全球第五大开发者,前十大其他都是上市公司,我们是唯一没有上市的公司,我相信我们也快了。
这次我们跟简寻合作,给各位小礼品里边应该有一个帆布袋,帆布袋有一个二维码扫描可以下载我们公司产品,我们主要做海外,所以对国内没有做特别的优化,国内手机也可能没有APUS,包括有些功能为了防止竞争对手抄袭就屏蔽,但是可以看我们产品总的功能。
今天我开发Android应用的稳定性问题。我先说为什么谈稳定性?其实也是我们过去,包括我们创业成立这家公司两年,以及我们之前别的公司,我们在移动互联网圈子里边做了这么多年以后最大感受是什么?最大感受达到亿及规模产品,健壮稳定是这个产品第一要务,这个我可以拿一些友商例子,很多用户并不在乎你有多少功能,你的功能多了只会觉得你用不着臃肿,用户大多数过呢差评都是稳定性差评,比如这个有一个评论,每次强行更新,每次更新不能动,卡死了。在座也有开发者,看到用户差评的时候,很多时候都是稳定性问题。
基本卡顿、闪退、莫名其妙的BUG,如果你真的有一亿用户,万分之一故障率就是一万用户,什么概念?粗略估算一个用户值10块,一万用户就是10万,其实值得你花钱雇别说10万,5万相当于工程师一个工资,可以花钱雇工程师解决这个问题。当你产品达到亿级的时候,稳定问题成为非常重要的问题。提到Android稳定性最喜欢说Android版本碎片化,这个我昨天从Google官网截图,自己统计版本分布情况,Android5.0占40%以上,Android4.4还有33%,4.4以下还有27%,你说27%用户不要了,意味着我们需要对每一个Android版本,或者至少达到一定规模,比如2.2版本只有1%也许可以考虑不支持了,但是其他几个呢?比如这个2.3、这个2.6%要不要支持?结合每家公司产品策略包括用户策略考虑要不要支持?到底稳定性和Android版本碎片化有什么关系?我网上搜一下发现很少人讲,有人提直接在代码判断一下就可以了,我判断Android5.0执行什么代码,这样我的程序是不是没有问题?它跟稳定性有什么关系?
我举实际遇到的问题,下面字比较小,我给大家讲一下。这个是Android系统已知道的BUG,在Android4.1上边如果开启辅助功能权限,如果下边访问这个网址100%会崩溃,这个网址特点,这个地方有一个问号、这个地方也有一个问号,一个正常的URL,用问号作为请求路径和分割符,如果参数又带一个问号严格来讲不合法的路径,这是某家公司企业内网的BUG,这个时候就是100%崩溃。大家如果看不清楚崩溃站,不在你代码里边。我要解决崩溃把代码包起来,崩溃没有一句在你代码里边,意味着没有办法把崩溃保护起来,有人说是不是对URL过滤呢?能解决一部分问题,但是发现有很多跳转跳过去,你能够拦截第一道网址不让他访问,但是跳转那个拦截不到,这个时候还是会崩溃。
这个问题是无解问题,别人给Google提了这个BUG,Google也记录了。最后Google回应什么?我们已经在内部版本已经修复,下一个大的版本升级更新。这个崩溃是Android4.1,我们在Android4.2改了,你就等用户升级Android4.2,4.1怎么办?他不管了,这样Android4.1用户现在还占7.8%,你有十分之一用户只要遇到这样网址就会崩溃,而且Google明确表示不会在这个版本修复,那你只能眼睁睁看着。
我再讲一个厂商ROM碎片化相关的崩溃,比如有些开发者平时用JNI开发,假如依赖JNI,教科书基本用下面方法加载,这么写确实没有问题,我们可以看一下Android原码实现路径,你调入Hello,首先把拼成完整的so,按照下面顺序寻找SO,第一在data额,第二环境变量寻找,通常三个目录,如果还没有找到会在LD—LIBRARY环境变量,通常也是这三个目录。
实际工作中间遇到哪些问题?第一如果预装APP怎么办?比如你们跟华为、小米合作,把你APP直接放到预装目录里边,不会自动释放APK的SO,你预装APP不会自动释放,需要手工把SO放到几个目录至少一个,比如你跟华为合作也好、小米合作也好,第一次这里有一个版本麻烦放一下,第二次再跟他又给你放,第三次你忘了说或者他忘了放,那你基本用的SO基本挂了。第二APK升级后,如果SO有更新怎么办?官方逻辑第一版本带来SO会释放目录去,如果你开发新的版本,它其实会替换原来旧的版本,把原来删重新弄新的,但是我们在实际过程中间,有一些厂商不知道处于什么考虑,他很奇怪,他仍然会继续加载system lib下边。举一个例子我跟一个厂商合作,后边发布新版本,新版本也更新,理论新版本装上应该有新的SO,如果按照上面安装原生的代码逻辑,应该自动加载新版SO,但是有的厂商不是仍然加载老的SO,出现什么问题,新版SO有新的方法、新的接法,你调的时候就崩了。还有普通的升级,三星手机上边,你升级一个APK,本来应该把老的SO删掉,新的SO释放进去,有的没有删掉,不知道为什么?你发现还是旧的,调用新的接口直接崩了。这些都是当你产品达到一定数量级不得不面对的问题。
Android系统固有的缺陷,直到今天Android系统仍然存在,并且Google官方不想改,我想找一个SDK打开视频文件,可能用一个getpackage  Manager为,少数用户会出现这个异常,在Android官方文档有一个解释,这个是系统服务,跟应用之间通过diect为,只有有限固定的长度大小1兆,并且它是你调进程的时候,如果没有结束相当于有一个队列的东西是所有调用共用这一1兆,如果你程序是多线程,为了加快界面速度共用,可能放一个线程共用,如果多线程启发非常容易超过1兆,崩溃就很容易出现。像这样Android涉及API不可靠,即便官方文档没有说常见,但是你一万用户会跑一个出来,你必须做准备。
还有内存泄露的问题,内存泄露跟稳定性有什么关系?各位开发者经常收到用户这样反馈。这样应用可以,刚启动很好,用的时间越长越慢,技术人感觉这里调没有问题,包括测试团队测的没有问题,但是到用户很卡,而且用户机型配置不低为什么卡?可能有些朋友遇到过,我们发现连16K内存都申请不下来,这是我们抓到崩溃,申请16K内存,这是有着2G内存的手机,发现申请16K内存都申请不下来,因为他告诉你现在只剩下14K空间,这些都是内存泄露的问题,你手机内存再大,跟你APP能用多少内存没有直接关系,基本你出厂的时候,已经把HOM大小配上,很多手机大概40兆左右,你超过这个大小就会出现这样的问题。
所以对于一款普通的APP,内存问题其实造成卡顿最重要的原因,JAVA其实做GC,这是一个真实的日志,每做一次GC用多少毫秒,我手机配置不错,基本一次GC70毫秒就可以,但是连续做几次GC,加起来100毫秒也可以忍。我这里简单说一下内存泄露的原理,其实这里边每一个环节真要讲的话可能讲一天,今天只是讲一个皮毛,内存泄露原理是什么,这是Android官方文档给一个典型的案例。Java对象是什么,发现对象没有人引用,就觉得你不再使用就释放掉,这个就是GC。首先第一个代码,参数进去节是this,我们再去看这个有一个CoatareVlew,这个地方已经有交叉应用,这两个之间相互引用,现在PC没有那么傻能够发现。关键这里,这个有Stackgroand,只要申请this其实全局对象,意味着Stackgorand不会释放,最后导致这个引用不会释放,可能放了所有代码都在里边,所有成员变量,即便这个SDK销毁,但是内存仍然存在。这是典型的内存泄露问题。
这个问题还比较好解决,有成熟的工具帮你们发现,今天我想重点讲的Android系统本身的内存泄露,刚才内存泄露是不合规的写法,只是用反面例子告诉大家内存泄露怎么来的。现在Android即便Google工程师常常小的疏忽造成内存泄露,并且内存泄露是系统级的,这个Google在Android5.01泄露,5.1修整,底下是修正代码,他有一个对象(英文),这个对象是单列,这个是(英文)变量,这个地方传了一个参数,单列变量关联了Ctsta,你一旦调用API接口,你又把(英文)作为(英文)参数传进去,最后被(英文)挂上,意味着永远不会销毁。最终结果进程运行完了,你退出本身图形资源释放,但是内存资源没有释放,接下来用户又申请一遍内存又退出,再进去再退出,反复内存不断累计,最后结果用户用几次越来越卡、越来越慢。这个问题在Android5.1改,5.0不打算改,只能平时注意。
前面我举很多例子,其实讲目前开发一个APP,在我印象中遇到哪些问题,这些问题怎么解决呢?
你要提高稳定性,基础先捕获住,比如前面遇到问题我怎么知道?因为在我手机没有问题,只有到用户手机才有问题,我怎么知道?第一解决崩溃捕获,作为入门推荐我推荐大家Fabric.io里的Crashlytics,我们适用过目前业界最好的。如果亿级规模最好自行捕获,有很多好处。第一让用户留下联系方式,比如你怎么浮现不出来?我看到崩溃改了,会不会出现新的问题?以前这个代码按照流程走下来,走到这里崩了,其实往下走不知道,这个时候复现非常知道,必须知道改了后边有没有新的问题。可以联系用户,让用户提供操作步骤、让用户配合收集手机环境,比如跟其他软件冲突了,我们联系用户告诉手机装那些APP,配合收集手机环境帮助复现崩溃。还有FIX之后让用户帮忙验证,一方面非常欢迎这个,觉得非常重视反馈意见,另外保证不用再发一个版本,让几千万、几亿客户当小柏树。还有可以分国家、分语言、分渠道、分版本统计。这点作为亿级规模非常重要,有一次我们崩溃是意大利崩溃,我们当时做多语言翻译,意大利语少写一个分号当时D写漏了,只有意大利语翻译不小心写漏了,就造成意大利崩溃。意大利对我们来讲是小国家,占我们用户比例比较低,整体看觉得崩溃率提高1%、2%,分国家看崩溃率一个国家达到20%,这个国家肯定有问题。
还有分渠道,在座有开发者如果成型公司,你们产品肯定对外推广,肯定有渠道A、渠道B、渠道C帮你们推广,但是渠道手可能不干净,可能重新捆一个包,捆刘流氓插件进去,没有注意可能带一个问题崩溃,分渠道看这个渠道崩溃率飙升20%,就知道渠道也出问题。包括分版本统计,新版本崩溃多少肯定做产品必看的数,自己做崩溃统计分纬度统计,帮助你发现问题。
我这里简单讲一下如何捕获,Java捕获非常简单,JNI崩溃,直接说你注册一个sigaction,目前大概捕获几个,比如SIGILL、SIGABRT等,总之捕获这些SIGNAL,提示用户我崩溃,能不能传回来数据帮助我们收集问题?留下联系方式如果他愿意的话,崩溃捕获只是告诉你有问题,这些问题怎么节么呢?我分享我们APUS经验,我们自己开发Framework,叫libLausanne,跟稳定性有关系三块:ROM自适配框架、内存热补丁、内存管理框架。
ROM自适配框架什么,我们Lausanne .load,相当于重新实现一遍,保证这段代码跑到ROM逻辑一致性,并且里边增加额外的处理,如果找不到SO文件,自动APK释放SO。即便那天跟谁合作,他忘了释放我们自己也能释放。另外作为开发的好习惯,我们跟国外知名大公司合作他们缺乏这方面意识,加载SO的时候一定加一个版本号,这是一个血泪的教训,就像前面我讲的,理论99%Android手机里边升级ADK都应该把新的SO升级上去,总是有手机不按常规走,你加载可能旧的,一个小的技巧在你SO后边加一个版本号,下次发布新版本变一下,最多你会发现找不到SO,至少不会加载旧的SO,找不到还好出来,可以从文件解压出来再给他加载,加载错了就更麻烦。
这个框架比如调用全部封起来,调用可能有异常,封起来相当于内部现场的队列,我保证调用的时候这个时间一定有一个线程调用它,其他调用都是后边排队,这个情况下PackageManager不会出现崩溃。包括内存泄露也是,刚才接口我们统一做封装,基本你传一个Lausanne作为指针传进去,我们内部也会(英文),这样可以避免内存的泄露。
内存热补丁,前面我不是举一个例子,Android4.1Google有一个100%闭线崩溃,崩溃怎么解?先看一下它的崩溃点,在这个代码里边Accessibilitylnjector.java,调用的(英文),其实崩的时候有一个(英文)异常,所以这个问题在Android4.2上边改的时候怎么改?很简单这么一个异常底下再加一个,其实很简单,Android4.1不改。我们做内存热补丁,内存把这个方法Patch掉,getAxs方法替换。内存热补丁怎么做到?原理不复杂,国内腾讯、LDE都实现,我们是第一家对ROMDalvik虚拟机首先有官方的接口,这个时候把JAVA作为参数传进去,可以拿到Method对象,其实在内存分布大概这样,第一字节、后边四节是对应的类,后边是访问标志、几个方法,中间还有几个,最后是native方法指针,要做的事情很简单,强制表示native方法,java调用这个方法的时候就认为是native方法,忽略原来的代码实现,你方法就是简单函数,他做的事情很简单,把请求转发写的java方法,新的方法替换旧的方法。
这个是ART虚拟机,原理差不多,ART虚拟机已经把java代码编译可执行代码,它反而更简单,他也是调官方接口拿到对象指针,里边全是内存指针,直接把指针全部替换新的代码就可以了。中间稍微有点难点64位指针计算跟32位指针计算不太一样,你会发现主动防御功能在ART有点问题,特别是64位CPU会有点问题,本身也不难相信后边还会改。
内存管理框架是解决内存泄露的问题,我推荐LeakCanary,监测到会把泄露点打出来,比较容易找到。当你代码规模达到几十万行时,清查内存泄露将是非常痛苦的过程,前面我举的系统本身内存泄露问题,包括WebView的内存泄露无法修复,怎么呢?我们采取新的思路,思想很简单,真正做很多细节需要做,退出进程是彻底的释放机制,我们做一种框架,把我们UI进程、后台常驻进程和任务进程全部拆开了,最后你会发现进程之间有一些通讯,我们做几个事情包括UI进程、后台常驻进程也好,比如我举一个例子,你从网上下一个文件,文件比较大半个小时到一个小时,下了不需要代码,剩下时间完全把内存释放,让用户感受它变更。
你说我做来电显示平时不能退,需要后台常驻,即便后台常驻也不用一直常驻,只要我确信这个常驻进程后边能被唤醒,像你做来电提醒的功能,显示来电号码的归属地,你做这么一个功能的话,其实理论上讲接受(英文),足够把代码唤醒起来,显示界面。但是发现有的手机ROM收不到或者收的很晚,可能电话挂了才能收到。之前有做来电归属地应用就曾经出现这个问题,ROM本身做一些定制,保证来电一定接起来,之前手机接到一个投诉,来了电死活接不通,恨不得把手机甩了。有来电显示作为后台常驻功能不被杀掉,有些功能确实需要放到后台,确定后台东西能够被唤醒,这个时候不需要后台常驻,我可以再退出。这些东西拿云端智能控制,到后边你会发现到底什么上边能退、什么不能退?确实需要有一个知识库。
比如我们可以做一个小实验,如果在某个手机上边,我自己被唤醒了,所有进程全部退掉,最后你发现手机收不到ROM,我作为开发者把产品发出去,我产品在那个手机唤醒不了,怎么告诉我?其实在云端统计,有一部分用户开启这个功能,有一部分用户没有开启这个功能,对于没有开启功能用户看到他的表现,有的用户直接把进程退了,退了不退我活跃没有受到任何影响,就知道这个进程没有问题。包括绿色守护、移动大师,包括上边装了软件,这些信息采集回来,可能这个组合下边比如有的用户用LBE绿色冷冻的功能,必须保证后台常驻。如果没有发现这个东西可能把这个东西关了。比如360新出手机有一部分冷冻功能,总之这些组合条件,通过云端判断,可以退就退,如果不退就不退,至少保证大部分用户手机内存都是最小的。
前面我开了个头讲一点皮毛,这是我微信的二维码,底下是我微信号,欢迎大家加我微信,具体技术问题我们可以交流。
提问:我有一个问题,刚才讲关于判断用户是否有LBE或者绿色水库,上传云端统计是否牵扯用户信息泄露?
张旭:我们公司产品稍微占点便宜,你装APP很正常知道,如果一款游戏有点吃亏。你要装友盟自动收集这个。
提问:(英文)发布之后在海外获得好评,我想知道当时项目开启为什么选择海外?还有一点和竞品相比,产品选择方面怎么考虑?
张旭:我尝试回答第一个问题,为什么选择做海外方向?今天主要技术交流,这个问题不想讲太长,简单讲一下,当初几个创始人包括李涛是我们CEO,我们一起讨论到底出来创业做什么?像李总过去在行业里边已经有15年工作经验,之前在很多公司当公司高管,我之前也是在百度、阿里、360这些公司任职,其实我们当时这些创始人最后达成一个共识,认为在当时选择创业时间点,当时有两个风口:第一O2O,第二海外,O2O大家已经看到今天很多负面新闻,当时判断O2O不是我们适合的,最后决定做海外,海外是一片广阔的蓝海,我也欢迎各位跟我们一块做海外市场。海外市场蓝海到什么程度?国内基本被BAT三家把持住,国内公司做的最好归属被BAT哪家收购?比如滴滴想被阿里收购就够了,独立APP也是在腾讯或者阿里系统里边,海外还是一片处女地。第一大家可以感受海外拿得出手互联网公司除了美国、中国也没有别的,之前我们也不明白,这些东西可能不在媒体上讲。
欧洲人挺有钱,但是欧洲为什么没有几家拿得出手互联网公司?其实欧洲人太懒了,这个话可能有点不正确,确实我自己亲身的感受,比如我们跟德国合作伙伴合作,德国当地非常有名的一家公司,他们早上十点上班,上班做的事情什么?十点来公司,先到咖啡间倒一杯咖啡,随便跟同事聊天,聊完11点,回去收收邮件该吃午饭,到下午四点就下班,他们下班也不回家,下班到外边找露天咖啡馆跟其他人聊天,这就是他们生活。包括德国人假期特别长,我们之前用他们产品遇到一个紧急的BUG联系他们修改,打电话给他们不好意思休假去了,两个星期回来。
假如我们是乙方,这个甲方早替换掉。包括希腊国家,前一段希腊不是游行,为什么游行?希腊人平时吃很多政府福利,把政府吃垮,政府没有钱,希腊人说吃不了就滚蛋。周六周日休假周一回来继续游行。欧洲人确实有钱确实太懒,没有办法跟中国人比,真正跟中国人勤比确实美国人,特别是加州美国人。当时去Google晚上10点路过,办公区灯火通明包括有员工进进出出,为什么中国、美国出这么牛逼的互联网公司?确实因为勤奋,反过来也是对我们一个机会,美国人有一个缺点,但是他很强势。
分享我过去在一家外企工作经历,也是跨国企业,我们是他们当时国内分公司,他要求全球统一标识,甚至连我们办公室凳子什么颜色都规定,比如他们公司吉祥色是紫色,所以我们办公椅子都是紫色,中国人不太喜欢紫色,他们说这是全球统一品牌,包括我们公司LOGO一个字母角度都写合同里边,改了他们法务找你麻烦。为什么海外互联网公司在中国做不起来?因为不尊重当地文化,易宝不允许买家和卖家直接联系,必须通过我平台才好收手续费。阿里很牛逼,不仅鼓励你直接联系,而且提供各种工具帮助你直接联系,当然阿里选择我要解决国内信用问题所以有支付宝担保,但是易贝不搞这些东西,最后结果他在国内做不起来。
其实我们出海印证我们判断,美国互联网公司在其他国家,其他国家人对他们非常不满意。比如Google在印度、马来基本捏着鼻子在用,没有别的选择只能用Google服务,当我们把产品介绍给他们用,他们觉得这个还这么用马上用我们,不再用Google。并且中国公司有一点很谦卑,只要是普遍客户需求,比如说阿拉伯语其实从右往左写,Google也是Android4.2才考虑从右往左写,对于习惯问题对中国公司根本不是问题,今天提超过100个问题认为普遍问题下一个版本就改,不用等两年。也让当地人感受到我们对他们的尊重。今天中国公司非常有机会,将来还会有更多中国公司出来,甚至有一天中国公司也许把美国公司赶出其他国家市场。
第二个问题也是出去介绍我们产品经常被人问到问题,其实我们产品起一个名字APUS,当时准备创业Google桌面已经上市3年,当时市值10亿美金,因为我们做的好他们跌到1.6亿美金,当时我们做的时候没有打算做一个桌面,其实想做用户系统。因为讲起来很抽象才改一个名字让用户理解,我们解决用户使用手机中间一切问题,回过头想一下,我们用手机初心什么?肯定不是买手机每天折腾这些东西,为什么那么人习惯用苹果?苹果手机买来简单弄一弄就很方便,Android明天要做清理、优化,为什么做这些东西呢?按理说我买手机不是被手机折腾,应该有简单的东西买来直接用,最后我们想做到一个目标,希望我们有这一套东西之后,用户再也不用操心你用手机问题,就像用苹果手机简单,这就是我们跟Google桌面和小米桌面最大不同,他们只是做桌面,而我们做用户系统。
提问:有没有回归国内市场?
张旭:我们不打算回归,过去我们做太长时间而且太累。而且国内竞争对手流氓手段确实觉得恶心。
提问:我是做手机系统APP,我们主要通过测试团队和自动测试保证这个,我们测试团队好几个,基本用户正常用操作不到的场景,我想了解测试这一块尽可能考虑更多的问题?
张旭:刚才问很好的问题,自动化测试,各种测试手段这些是基本功,做一款产品上线前一定做这些测试,我今天讲的手段常规手段覆盖不到的问题,Android碎片化问题太严重,现在上百台测试机,不同机器、不同厂商、不同版本,即便这样发现我们产品出去远远不够,当你用户规模达到一定程度会发现,各种在你这里不可能出现的问题,在用户都会遇到。你讲的这些东西是基本功,作为产品级一定自动化测试、单点测试、子代率测试,但这些是常规手段,除了这些手段之外还应该认识到外边很多用户有意想不到的情况,而且必须有手段处理他们情况,其实今天我跟各位向主要这部分,因为这部分在网上资料非常少。
77 views
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
GDPR实战指导:谷歌是如何设计并获得用户“同意”的?
Android将允许纯C/C++开发应用
买iPhone 7 还是 Huawei P9?
推荐10个易上手好用的H5网页编辑工具
安卓手机经常很卡甚至发烫,到底怎么回事?
Android8.0的到来压缩了手机厂商的生存空间
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服