第三方推送平台 能给pc端推送应用推送吗

【求助】关于服务端推送消息到客户端,比如推送到手机终端等……【java吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:666,649贴子:
【求助】关于服务端推送消息到客户端,比如推送到手机终端等……收藏
求助一下吧里各位前辈们,有做过类似功能模块的吗?项目中目前使用的是手动点击按钮然后从后台获取数据,但是这样每次都要手动点击。上头要求服务端每次修改数据后,实时推送到客户端。例如安卓手机客户端、浏览器客户端页面,实时收到消息推送手机客户端类似于百度贴吧或者是新浪微博那样提醒,或者是手机当前的数据自动刷新而电脑客户端页面则需要在服务端修改数据后进行数据刷新以前没做过类似的功能模块,现在感觉焦头烂额,网上说的技术五花八门,看的头昏脑胀想请教下吧里的前辈们有没有这方面的意见或者是建议,让我有点思路劳烦各位前辈了,不胜感激。
2017java学习来上市公司博为峰学java,入学即签就业协议,不就业不收费,查看java课程!java好学吗?java课程来博为峰学,java工程师就业年薪十几万!
定时往服务器拿数据就好了,频率高点,比如3秒5秒的
开源的apn。或者第三方公司的jpush,个推。
主动请求+缓存。
据说websocket
comet最靠谱,tomcat有实现,楼主可以试试。有demo了。也给他说说。
最常用的就是轮询机制,也就是定时请求
XAMPP 这个你可以看看 或者MQTT
兄弟连教育&拉勾网强强联合打造JavaEE.战狼班,Java培训后付费非贷款,入学兄弟连java战狼班,拉勾网战略合作,高起点出Java精英.
汉语:我是来打酱油的。英语: I'm going to buy some soy sauce.  韩语: 나는 간장 소스.德语: ich gehe Sojasosse kaufen. 法语: je me suis prend que sauce de soja. 俄语: Я пришла за соевым соусом.荷兰语:kwam ik tot een sojasaus 西班牙语:me vino a un salsa de soja 意大利语:venuta solo a comprare la salsa di soia.你每到一个帖子就粘贴这句话,十五天就到了11级”......我彻底恍然大悟!!!!
轮询方式或自己搭建推送服务器,遵循XMPP协议的openfire+asmark就能实现。
不同平台实现方式不同。。这个需要具体情况具体分析。比如百度贴吧,在页面上是 ajax , 在手机上是apn这个没什么通用的,没有银弹。
手机可以用jpush之类的第三方sdk,免费的。网页简单点用轮询就好啦
做过,现在是定时去请求服务器。服务器走jdbc查询数据库。结果集(xml)缓存在redis,后续请求如果是相同条件直接走redis。目前有打算改成用百度push,不过百度push不太稳定,偶尔会宕机。而且push消息发送太快居然也会出错。并且还无法实现我们目前已经做到的分省市运营商推送
前辈你好我不知道
轮询 都可以达到目的。
不懂帮顶。。
最好用推送,百度推送,极光推送都可以的。轮询费电呀。
听说豆票能换补签卡,回帖又能给豆票
23种经典java设计模式中有一种叫做“观察者模式”的……和那个类似……只不过使用了互联网媒介……唯一压力大一点的就是服务器的连接数……
轮询,长链接,都不难,但耗资源,服务器压力大,最佳实现就是websocket,浏览器对HTML5支持都非常好,即使有不支持的也可以用js给出提示
安卓没做过,WEB的ajax推特简单 可以给你个demo
好像mqtt还行,不过直接用第三方的不就完了╮(╯▽╰)╭
谢谢各位前辈们的指导,感激不尽
客户端发请求,服务器hold住,直到有信消息才返回,或者是到了一定时间。客户端收到响应马上再发一个请求。
客户端开启一个服务
登录百度帐号推荐应用24被浏览6213分享邀请回答6添加评论分享收藏感谢收起3添加评论分享收藏感谢收起查看更多回答Android端外推送到底有多烦?a year ago2收藏分享举报文章被以下专栏收录有时候写点技术干货,有时候写点有趣的文章。推荐阅读{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&以发布技术文章为主,涉及Android\u002FiOS开发,以及后端架构。间或写点人生感悟,关注技术人员的个人成长话题。&,&permission&:&COLUMN_PUBLIC&,&memberId&:,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&有时候写点技术干货,有时候写点有趣的文章。&,&urlToken&:&zhangtielei&,&id&:16260,&imagePath&:&f4ffaceacd.jpeg&,&slug&:&zhangtielei&,&applyReason&:&0&,&name&:&铁蕾的IT专栏&,&title&:&铁蕾的IT专栏&,&url&:&https:\u002F\\u002Fzhangtielei&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:63,&avatar&:{&id&:&f4ffaceacd&,&template&:&https:\u002F\\u002F{id}_{size}.jpeg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\\u002Ff4ffaceacd_l.jpeg&,&articlesCount&:11},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\\u002F6c68d866f568f3bde1fd2_r.png&,&lastUpdated&:,&imagePath&:&6c68d866f568f3bde1fd2.png&,&permission&:&ARTICLE_PUBLIC&,&topics&:[,6231],&summary&:&(原文首发于微信公众号:\u003Cb\u003E张铁蕾\u003C\u002Fb\u003E,)说Android端外推送比较烦,实际有两层意思:首先是说实现上比较麻烦,至今业界也没有找到一种完美的解决方案,Android程序员通常需要同时集成多家推送平台(如果有自己的端内推送,还要考虑与端内推送的配合)…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T22:25:32+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:1169595,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&Android端外推送到底有多烦?&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:16260,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\\u002F6c68d866f568f3bde1fd2_r.png&,&author&:{&bio&:&微爱CTO;微信公众号:tielei-blog;个人网址:&,&isFollowing&:false,&hash&:&a71c7f23e932ccaae143207e&,&uid&:384000,&isOrg&:false,&slug&:&zhtielei&,&isFollowed&:false,&description&:&老程序猿,全栈攻城狮,微爱CTO。\n分享技术干货,探讨个人成长。&,&name&:&张铁蕾&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzhtielei&,&avatar&:{&id&:&b08f1ba6c18efc6b6fdb68&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:432505}],&title&:&Android端外推送到底有多烦?&,&author&:&zhtielei&,&content&:&\u003Cp\u003E(原文首发于微信公众号:\u003Cb\u003E张铁蕾\u003C\u002Fb\u003E,)\u003C\u002Fp\u003E\u003Cp\u003E说Android端外推送比较烦,实际有两层意思:首先是说实现上比较麻烦,至今业界也没有找到一种完美的解决方案,Android程序员通常需要同时集成多家推送平台(如果有自己的端内推送,还要考虑与端内推送的配合);其次是说Android推送的市场现状比较混乱,无论选择哪一家,都让人纠结万分,难免心情烦躁。无论是你花费了多少功夫,做了多少优化,仍然可能存在推送不到或推送延迟的情况。\u003C\u002Fp\u003E\u003Cp\u003E网上已经有很多关于Android推送的讨论,但很少有站在App开发者(特别是开发App的创业团队)的角度来进行介绍的文章。本文的目的,就是站在一个App开发团队的角度,集中讨论两方面的问题:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E如何对各家的推送平台进行技术选型;\u003C\u002Fli\u003E\u003Cli\u003E在集成各家推送平台的SDK的时候,应该重点关注哪些问题。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch4\u003E为什么本文只讨论端外推送?\u003C\u002Fh4\u003E\u003Cp\u003E通常大厂的App都会区分端内推送和端外推送(端指的是客户端),具体说来:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E当App在前台运行的时候,这时的推送称为端内推送。端内推送一般是走App自己实现的一套推送系统:推送服务器是自己的,客户端维护一条长连接连到自己的推送服务器,不依赖任何第三方的推送系统。\u003C\u002Fli\u003E\u003Cli\u003E当App从前台退到后台,在短时间内App未被杀死前,App自己的长连接仍然有效。这时的推送可以仍然走App自己的推送系统。所谓的“Android进程保活”,就是为了尽量延长这段在后台存活的时间。\u003C\u002Fli\u003E\u003Cli\u003E当App在后台运行足够长的时间后,App进程由于被清理或者其它原因,App自己的长连接断开。这时的推送就称为端外推送了,只能走某个第三方推送平台了。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E从这个过程来看,大厂的App的推送策略可以概括为:优先使用自己的推送,实在不行再走第三方推送平台。为什么这样呢?因为自己的推送系统更快、更有保障:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E更快,是因为你交给第三方推送平台的推送消息要跟很多其它家App的消息一起排队。如果某家App突然在短时间内发送大量推送消息给推送平台(推广活动,或者程序bug),那么这个推送平台上的其它App就有可能受到牵连,推送延迟变得很大。这样的情况是很可能会发生的。比如,在某个推送平台的技术交流群里,不定期地就会看到有人在喊:“是不是推送又堵了啊......”\u003C\u002Fli\u003E\u003Cli\u003E更有保障。大厂通常有专门的队伍维护推送相关的服务,有问题可以快速推进优化。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E我们虽然算不上大厂,但我们维护的\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=http%3A\\u002F\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E微爱\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003EApp也是有自己独立的端内推送的,而端外采用另外几家推送平台,后面我们再详细讲。\u003C\u002Fp\u003E\u003Cp\u003E那为什么本文只讨论端外推送呢?因为讨论端内推送和讨论端外推送是完全不同的两个话题。讨论端外推送,我们主要是在讨论怎么对各家的推送平台进行选择,以及集成各家SDK的时候我们应该重点注意哪些问题。这通常是很多初创团队更需要的。\u003C\u002Fp\u003E\u003Cp\u003E而讨论端内推送,主要应该讨论一个推送系统的具体实现,这是一个比较复杂的问题,并不是一篇文章就能讨论清楚的。在这里,我们只是浮光掠影地浏览一下这个话题可能涉及到的内容,但不做展开讨论:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E采用什么协议?XMPP还是MQTT还是自定义二进制协议?是否像微信一样,需要推送二进制数据(比如短语音和缩略图数据)?\u003C\u002Fli\u003E\u003Cli\u003E如何保证后台长连接不死?涉及到“保活”的问题。\u003C\u002Fli\u003E\u003Cli\u003E如何做才能真正保证不丢数据?涉及到系统的方方面面,比如消息的确认,客户端和服务器的数据同步,客户端的数据存储的事务保证,后台消息队列如何设计保证不丢数据。如果是IM,离线数据如何处理?\u003C\u002Fli\u003E\u003Cli\u003E长连接的Keep Alive和连接状态的检测与维护。比如XMPP相当于一个永远解析不完的XML流,使用一个空格作为Keep Alive消息。\u003C\u002Fli\u003E\u003Cli\u003E长连接的安全性。验证以及加密。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E综上,本文要讨论的重点是端外推送。\u003C\u002Fp\u003E\u003Ch4\u003E有哪些推送平台可以选择?\u003C\u002Fh4\u003E\u003Cp\u003E端外推送我们必须依赖第三方的推送平台了。\u003C\u002Fp\u003E\u003Cp\u003E这个情况其实本来跟iOS上类似。在端内推送系统的长连接失效的时候,我们就只能通过其它的推送平台来完成。在iOS上我们只用使用APNs就行了。\u003C\u002Fp\u003E\u003Cp\u003E而在Android上,跟APNS对应的服务是谷歌的GCM (Google Cloud Messaging),但很可惜它在国内的可用性不高(主要原因是手机厂商对Android系统的定制化,可能会将GCM服务裁减掉,以及国内运营商的一些限制)。如果我们做的是一个海外的应用,那么端外推送基本只用考虑GCM就可以了。\u003C\u002Fp\u003E\u003Cp\u003E那国内的Android推送平台有哪些可以选择呢?\u003C\u002Fp\u003E\u003Cp\u003E根据我个人了解到的信息,我列出了下面这些(排名不分先后):\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E小米推送(MiPush)\u003C\u002Fli\u003E\u003Cli\u003E华为推送(华为Push)\u003C\u002Fli\u003E\u003Cli\u003E友盟推送(U-Push)\u003C\u002Fli\u003E\u003Cli\u003E个推\u003C\u002Fli\u003E\u003Cli\u003E极光推送\u003C\u002Fli\u003E\u003Cli\u003E阿里云移动推送(Alibaba Cloud Channel Service)\u003C\u002Fli\u003E\u003Cli\u003E腾讯信鸽推送\u003C\u002Fli\u003E\u003Cli\u003E百度云推送\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch4\u003E我们选的是哪家推送?选择标准是什么?\u003C\u002Fh4\u003E\u003Cp\u003E上面提到的各推送平台大体可以分为三大类:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E大手机厂商的推送:小米推送、华为推送。\u003C\u002Fli\u003E\u003Cli\u003E专业的第三方推送:友盟推送、个推、极光推送\u003C\u002Fli\u003E\u003Cli\u003EBAT大厂的平台推送:阿里云移动推送、腾讯信鸽推送、百度云推送。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E要对这些推送平台进行选择,我们首先要知道各类推送平台的优势分别是什么。\u003C\u002Fp\u003E\u003Cp\u003E首先,对于手机厂商的推送,他们的推送服务在他们自己生产的手机上属于系统级别的服务,理论上来说,手机系统对他们自家的推送限制最小。\u003C\u002Fp\u003E\u003Cp\u003E比如,在小米手机上,不在系统自启动名单里的App,在手机重启后,App声明的后台Service并不会自动运行。但是,小米推送作为手机系统级服务,仍然是可以收到推送的。\u003C\u002Fp\u003E\u003Cp\u003E同样,华为推送的技术团队也对外宣称(原话):\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E华为Push,在华为手机上是系统级别的服务,稳定性等各方面肯定都会好些。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E但是,即使是系统级别的推送服务,也不是百分百保证消息送达。这里比较奇葩的是华为推送,下面是他们技术支持给出的描述(原话):\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E华为手机上:Emui3.0上,Push广播有很大概率被限制,如: Mate7 3.0版本,荣耀6plus,P7 3.0版本,4X, 4A等。Emui3.1上,Push广播基本不被限制,但个别型号机型存在问题,如:荣耀5x等。Emui4.0及以上,Push广播有较高概率被限制,不被限制的机型如:荣耀畅玩4C,荣耀畅玩4X,Mate S,P8 MAX等。如广播被限制,需要将应用设为开机启动项。所以对于及时性或到达率要求非常高的应用,我们建议应用要考虑替代方案。后续Push版本,华为将采用新的设计方案,解决被限制的问题,但发布计划待定。\u003C\u002Fp\u003E\u003Cp\u003E另外,至于限制的问题,其实华为sdk还是能接收到推送消息的,当将消息通过广播发送给应用是,如果手机管家查到该应用处于stop状态,那么会拦截该广播的。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E看完之后的感觉:还真他妈复杂!\u003C\u002Fp\u003E\u003Cp\u003E总之,华为手机上的推送,华为推送自己也不太完全能搞得定的。但是,我们考虑再三,似乎也没有更好的选择了。\u003C\u002Fp\u003E\u003Cp\u003E再说第二类:专业的第三方推送。他们的优势看什么呢?看他们“保活”和“互拉”的能力。举个例子,假设你接入了友盟,而恰好今日头条也接入了友盟。有一天你的App被杀死了,但是今日头条的装机量估计比你的要大啊,这时用户启动了今日头条,那么推送系统也就会通过共享的推送通道顺便把你推送消息送达到手机上,然后还可能把你的进程也唤醒(被“保活”了)。\u003C\u002Fp\u003E\u003Cp\u003E这么说来,选第三方推送平台,这个推送平台的规模效应就很重要了。那如何得知他们的规模和市场份额呢?最好的办法是问内部的朋友。否则,其实也没什么好的办法,每家肯定对外都说自己最好啊。有一个不太精准的方法,就是看他们的合作客户里有哪些大的app,到他们官网上的合作案例里去看。这个信息总不能乱写把。\u003C\u002Fp\u003E\u003Cp\u003E而对于BAT大厂的推送呢?看起来并没有什么优势。各家的“全家桶”采用的“保活”阵营和推送通道,跟他们开放出来的是两码事。比如,你不要以为用了腾讯信鸽推送,就能占上微信的光。\u003C\u002Fp\u003E\u003Cp\u003E这里需要单独提一下的是阿里云的移动推送。在他们官网上提到,手机淘宝就是用了阿里云的这个推送。不过仔细研究一下会发现,手机淘宝也在同时使用其它的第三方推送平台啊(比如友盟推送)。两个平台到底谁借谁的力更多呢?不得而知啊。\u003C\u002Fp\u003E\u003Cp\u003E综合上面的分析,我们在\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=http%3A\\u002F\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E微爱\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E的Android客户端里使用的推送方案基本如下所述:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E端内使用微爱自己的推送;\u003C\u002Fli\u003E\u003Cli\u003E端外在小米手机上使用小米推送;\u003C\u002Fli\u003E\u003Cli\u003E端外在华为手机上使用华为推送;\u003C\u002Fli\u003E\u003Cli\u003E端外在其它手机上统一使用一种推送,也就是上面推送平台列表中的某一个。具体是哪个就不说了,本文中我们称它为X-Push吧。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E注意:小米推送在非小米手机上当然也能工作,只不过就不是系统级别的服务了,受的限制就多一点。同理,华为手机也一样。我们之所以这样选择,是为了让不同的推送运行在各自擅长的环境里。\u003C\u002Fp\u003E\u003Cp\u003E基本的架构图如下:\u003C\u002Fp\u003E\u003Cnoscript\u003E\u003Cimg src=\&https:\u002F\\u002F20d6e9eb1ef6e29ba53c_b.png\& data-rawwidth=\&3208\& data-rawheight=\&2174\& class=\&origin_image zh-lightbox-thumb\& width=\&3208\& data-original=\&https:\u002F\\u002F20d6e9eb1ef6e29ba53c_r.png\&\u003E\u003C\u002Fnoscript\u003E\u003Cimg src=\&data:image\u002Fsvg+utf8,&svg%20xmlns='http:\u002F\u002Fwww.w3.org\u002FFsvg'%20width='3208'%20height='2174'&&\u002Fsvg&\& data-rawwidth=\&3208\& data-rawheight=\&2174\& class=\&origin_image zh-lightbox-thumb lazy\& width=\&3208\& data-original=\&https:\u002F\\u002F20d6e9eb1ef6e29ba53c_r.png\& data-actualsrc=\&https:\u002F\\u002F20d6e9eb1ef6e29ba53c_b.png\&\u003E\u003Cp\u003E本来呢,对于推送平台的选择问题,到这里就应该结束了。但是,最近发生了一件事,让我们觉得被X-Push这家坑了一把,这让我们突然意识到了一个选择陷阱。现在把它分享出来,好让大家选择的时候一定要擦亮眼睛。\u003C\u002Fp\u003E\u003Cp\u003E事情大致经过是这样的:我们开始集成X-Push这家推送的时候,使用的是免费版服务。但是,我们用了一段时间之后,他们的销售找了过来。宣称他们SDK里的“看护功能”,是付费功能,如果不付费,技术那边就会通过一些操作关闭这一功能。这里他们提到的“看护功能”,大概就是本文前面提到的“保活”和“互拉”的能力。\u003C\u002Fp\u003E\u003Cp\u003E这个事情的关键点在于什么呢?\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E我们一直以来都认为对于这类第三方推送平台,“看护功能”是他们最基础的一个功能。我们在整个接入开发的过程中,没有从任何来源得到关于“看护功能”要单独收费的说明。他们官网上的公开价格表压根没有提到这个功能,接入的技术支持QQ群里也没有任何人提到过,官方的开发文档更是无处提及。\u003C\u002Fli\u003E\u003Cli\u003E我们在整个接入和测试的过程中,以及后来上线之后运行的这段时期内,这个“看护功能”都是一直包含在SDK内的。等用了一段时间之后,却突然被告知这一基础功能要收费,实在让人措手不及。\u003C\u002Fli\u003E\u003Cli\u003E如果明码标价,我们在最开始选型的时候就会把这一因素考虑进去。但是该平台却在开始的时候故意隐藏可能存在的收费陷阱。\u003C\u002Fli\u003E\u003Cli\u003E对方称如果被关闭了“看护功能”,那么“消息触达效果”会有明显地降低。我们也能理解“免费+收费”的商业模式,但是通常来讲,这种模式是对于基础功能免费,而对于高级功能收费,很少见到以降低服务质量作为免费条件的。\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cp\u003E如果把这件事的全部细节写出来,恐怕还需要额外的5000字。由于本文的主要目的还是分享技术选型的经验,所以这里点到为止,能把事情的大致经过说清楚就好了。等这件事尘埃落定以后,我们也许还有机会再重新拿出来讲一讲这个故事。\u003C\u002Fp\u003E\u003Cp\u003E但是,这里你要记住的是,在你选择一家推送平台之前,一定要找人问清楚对方收费的模式,有没有隐性的消费陷阱。记住:没有人主动会告诉你哟。\u003C\u002Fp\u003E\u003Cp\u003E大家也别问这家X-Push到底是哪家了,大家自己去体会。这里能起到提醒的作用就够了。\u003C\u002Fp\u003E\u003Ch4\u003E你是否需要自己的端内推送?\u003C\u002Fh4\u003E\u003Cp\u003E对于小的创业团队来说,自己实现端内的长连接推送系统,成本还是不小的。\u003C\u002Fp\u003E\u003Cp\u003E其实呢,各个第三方推送平台也是可以在端内使用的。而且,他们一般也对iOS的APNs推送也有封装。所以,在资源紧缺的情况下,小团队在初期也可以选择某家第三方推送平台做自己全部的推送服务,能快速地同时支持Android和iOS两个平台推送。等后边人手充裕了,再考虑进行优化,或加入新的推送渠道。\u003C\u002Fp\u003E\u003Cp\u003E具体怎样选择,还在于你自己权衡。\u003C\u002Fp\u003E\u003Ch4\u003E使用通知栏消息还是透传消息?\u003C\u002Fh4\u003E\u003Cp\u003E通常第三方推送平台都支持两种推送消息类型:通知栏消息和透传消息。\u003C\u002Fp\u003E\u003Cp\u003E通知栏消息,在被送达用户的设备后,直接以系统通知的形式展示给用户。它不会继续被传递到App。\u003C\u002Fp\u003E\u003Cp\u003E而透传消息,在被送达用户的设备后,还会继续路由到App,通过回调App的某个BroadcastReceiver的形式将消息传递到App内部。然后由App决定如何处理和显示这个消息。\u003C\u002Fp\u003E\u003Cp\u003E这两类消息在送达率的保证上有所不同,当然在提供的编程能力上也非常不同。\u003C\u002Fp\u003E\u003Cp\u003E透传消息在整个消息传递过程中比通知栏消息多了一步,因此就增加一些被系统限制的概率。所以说,通知栏消息比透传消息应该能提供更好的送达率。\u003C\u002Fp\u003E\u003Cp\u003E比如,小米推送的文档中就这样描述:\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E在一些 Android 系统(如 MIUI)中,受到系统自启动管理设置的限制,应用不能在后台自启动。在这类系统中,如果在发送消息的时候对应的应用没有被启动,透传类消息将不能顺利送达。因此,对于对送达率要求很高的消息,建议尽量采用通知栏提醒的方式推送消息\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E如果App有自己的端内推送系统,那么这种通知栏推送消息就更合适一些。当端内推送的长连接失效时,我们通过通知栏消息把提醒展示给用户,由用户唤起我们的App,然后真正的消息数据再经由端内推送达到客户端。\u003C\u002Fp\u003E\u003Cp\u003E实际上,我们就是采用通知栏消息这种推送方式的。\u003C\u002Fp\u003E\u003Cp\u003E而透传消息,提供了对消息数据的更灵活的操纵能力。App如果仅仅通过通知栏消息,是无法接触到消息数据本身的。\u003C\u002Fp\u003E\u003Cp\u003E所以,如果App没有自己的端内推送系统,而是采用第三方推送作为端内推送通道,那么就只能使用透传消息。\u003C\u002Fp\u003E\u003Cp\u003E另外一个例子,如果App想自定义通知提醒的样式,以及提示声音,恐怕也只能通过透传消息来自己实现。通知栏消息通常提供不了那么灵活的配置。\u003C\u002Fp\u003E\u003Cp\u003E这里有一点需要说明的是,当透传消息送达设备后,如果在试图路由到App内部的时候,发现App进程不在,那么理想情况下它应该“拉起”App进程。所以,照此推测,如果前面提到的那家X-Push关闭了“看护功能”的话,那么透传消息会受到多大的影响呢?结果可想而知。另外,X-Push那家的销售说了,关闭“看护功能”,对通知栏消息的“消息触达效果”也是有影响的。无语......\u003C\u002Fp\u003E\u003Ch4\u003E推送的初始化和推送token的同步\u003C\u002Fh4\u003E\u003Cp\u003E我们使用第三方推送平台,最关键的地方在于前两个步骤:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E在恰当的时机把推送SDK初始化起来。\u003C\u002Fli\u003E\u003Cli\u003E初始化之后App会异步地收到一个推送token,那么接下来需要把这个推送token同步到App服务器。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E这里的推送token,在不同的推送平台上的叫法不太一样,比如在小米推送中被称为reg id,在华为推送中被称为token,在个推中被称为cid,在友盟推送被称为Device Token。总之,它是推送平台对设备的唯一标识。我们这里统称它为“推送token”是为了方便讨论。\u003C\u002Fp\u003E\u003Cp\u003EApp的客户端拿到它之后,必须要同步到自己的服务器,并与自己的用户ID建立起对应关系。这样当我们想推送消息给我们的某个用户的时候,我们才能查到对应的推送token。\u003C\u002Fp\u003E\u003Cp\u003E前面说的初始化和推送token同步这两个步骤,看起来很简单,只是调用SDK的现成接口,再把它发送给服务器而已。但是,好的代码不仅能在正常情况下工作,还应该充分考虑失败情况。有什么样的失败情况需要我们考虑呢?我们以小米推送为例来分析一下:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E小米推送要求在Application对象的onCreate中执行初始化操作。我们可以猜测一下,在这个初始化操作中小米推送的SDK可能需要在本地为我们修改配置,还可能需要联系小米推送的服务器来申请reg id(即推送token)。这个初始化过程是可能失败的,本地操作可能会受到系统的限制,网络更是可能出错。试想,如果初始化出错了,我们还会收到推送token吗?\u003C\u002Fli\u003E\u003Cli\u003E假设我们成功收到了推送token(通常在一个BroadcastReceiver中),接下来把推送token发送到我们自己的服务器,这个工作需要我们自己来完成了。我们都知道在移动环境下网络很可能是弱网环境,这次同步如果失败了,那么下次要等到什么机会才能再次进行同步呢?\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E上述第一种初始化错误,理应由推送SDK来处理。如果失败,它应该会有重试机制,直到成功获取了推送token,它再重新调用App把推送token传过来。比如,小米推送平台也是这么宣称的,初始化可能出现的错误,App开发者不用考虑。如果你充分信任推送平台,那么这个错误其实是可以不用去考虑的;否则,你可以在App里增加某些机会来检测初始化是否已经成功(可以通过检测是否已经拿到推送token来确定),然后在恰当的时机重新调用初始化代码。当然,在做这个事情之前,你最好与推送平台沟通清楚,确保重复调用初始化代码不会产生什么副作用。\u003C\u002Fp\u003E\u003Cp\u003E上述第二种错误,就必须靠App开发者自己处理了。这里我们实际上需要在App客户端和服务器之间抽象出一条强的通信通道,我们把同步推送token的请求放进去,这条通信通道能够在失败发生的时候自动重试。\u003C\u002Fp\u003E\u003Cp\u003E这里的代码写得是不是足够健壮(robust),不同level的程序员就高下立判了。\u003C\u002Fp\u003E\u003Cp\u003E我们可以说,\u003Cstrong\u003E恰当而全面地处理失败情况才能真正体现工程师的意义\u003C\u002Fstrong\u003E,这也是工程和理论研究的不同点之一。\u003C\u002Fp\u003E\u003Ch4\u003E推送的送达率到底跟什么有关?\u003C\u002Fh4\u003E\u003Cp\u003E推送做得好不好,以及我们选择推送平台选的好不好,关键在于送达率高不高。送达率这个概念,一直是个很混乱的概念,有些平台会宣称送达率能达到98%以上,而又有一些人说行业平均水平也就60%左右。\u003C\u002Fp\u003E\u003Cp\u003E为什么说法如此迥异呢?是因为大家在说的其实不是一个送达率。\u003C\u002Fp\u003E\u003Cp\u003E友盟的消息推送业务线负责人陈漠沙曾专门写过一篇文章,来澄清送达率概念的一些误解,文章写得相当好,建议做推送业务的同学一定要读一下:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002F%25E5%25B7%25A5%25E7%25A8%258B%25E6%258A%%259C%25AF\u002F4541.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E推送“送达率”概念太模糊?友盟带你解读“送达率”背后的那些指标\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E关键是要分清此文中定义的“在线送达率”和“通用送达率”。\u003C\u002Fp\u003E\u003Cp\u003E“在线送达率”,各个推送平台优化到最后,可能都差不多。估计都能达到98%以上。\u003C\u002Fp\u003E\u003Cp\u003E而“通用送达率”才是真真正正把消息推送到你的App的最终的送达率,这个也才是用户最终能感受到的送达率。App开发者需要真正关注的也是这个。\u003C\u002Fp\u003E\u003Cp\u003E“通用送达率”大概来讲,是最终到达App的消息数与开始发出的消息数的比率(在一定时间内监测)。跟这个比率直接有关的因素是两个:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E业务类型。比如你的App是个IM,那么可能通用送达率会比较高,因为IM来的消息比较重要,且需要接收的人尽快去阅读处理。而如果你的App只是来推送一些系统消息,那么很多人可能压根不会打开你的App去看,这样通用送达率自然就低。\u003C\u002Fli\u003E\u003Cli\u003E推送的调用方式。这个和开发有关。比如,你的推送逻辑总给已经卸载了App的用户发送消息,那么对方肯定收不到了,造成通用送达率比较低。这种情况在群发的时候尤其显著。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E所以,这么说起来,不同的App由于业务不同,推送调用方式也不同,那么他们的通用送达率就没有实质的可比性。\u003C\u002Fp\u003E\u003Cp\u003E那假如我们推送做了某个优化,或者某天换了一个更好的第三方推送平台,我们怎么知道这个改动是好还是坏呢?答案是我们可以自己跟自己比。持续监测通用送达率,比较改动前后的变化。\u003C\u002Fp\u003E\u003Ch4\u003E拥抱变化\u003C\u002Fh4\u003E\u003Cp\u003EGitHub上有一个讨论Android推送的帖子(由@Trinea创建):\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fandroid-cn\u002Ftopics\u002Fissues\u002F4%23issuecomment-\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EAndroid 第三方 Push 推送方案使用调查\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E这个帖子从2015年5月份开始讨论至今,仍然没有人给出一个完美的解决方案。\u003C\u002Fp\u003E\u003Cp\u003E随着各个手机厂商的市场份额的变化,以及推送平台市场的变化,Android推送也是一个不断处于变化中的话题。今天的结论,换到明天,也许就未必再适用。\u003C\u002Fp\u003E\u003Cp\u003E所以,推送服务的实现者们也当然要拥抱变化。\u003Cstrong\u003E一定要确保你的推送架构能够很容易地切换某个第三方的推送渠道\u003C\u002Fstrong\u003E。\u003C\u002Fp\u003E\u003Cp\u003E多年的创业经验告诉我们,不只是推送服务,也包括众多其它的云服务,仅仅依赖一家平台的做法,都是极其愚蠢的。\u003C\u002Fp\u003E\u003Cp\u003E由于国内的各大手机厂商对于安卓系统做了各种不同的定制,增加了很多安全性的限制,导致推送成了一个很复杂的问题。而这个市场中又没有哪一家完美解决了所有手机设备的推送送达的问题。同时,微信由于其先发优势和规模优势,进入了各大厂商受保护的白名单,进一步拉开了与其他App在推送送达率上的距离。\u003C\u002Fp\u003E\u003Cp\u003E最后不由得感慨一句,如果谷歌一直在中国,还会有这种乱局出现吗?\u003C\u002Fp\u003E&,&updated&:new Date(&T14:25:32.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:0,&collapsedCount&:0,&likeCount&:2,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F6c68d866f568f3bde1fd2_r.png&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Android 开发&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Android 消息推送&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&推送 (Push)&}],&adminClosedComment&:false,&titleImageSize&:{&width&:1593,&height&:1080},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&zhangtielei&,&name&:&铁蕾的IT专栏&},&tipjarState&:&inactivated&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:0,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T22:25:32+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&产品\u002F咖啡\u002FUKE\u002F三猫&,&isFollowing&:false,&hash&:&6c2caa84dbd&,&uid&:52,&isOrg&:false,&slug&:&cress&,&isFollowed&:false,&description&:&你知道的太少了&,&name&:&cress&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fcress&,&avatar&:{&id&:&v2-d86e7a0bccdcdeb853302ed&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&勇敢的心&,&isFollowing&:false,&hash&:&f16ede99db547f2fa14b9be&,&uid&:84,&isOrg&:false,&slug&:&sha-mo-34-9&,&isFollowed&:false,&description&:&&,&name&:&沙漠&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fsha-mo-34-9&,&avatar&:{&id&:&a9b9bcb1d&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&\u003Cimg src=\&https:\u002F\\u002F20d6e9eb1ef6e29ba53c_200x112.png\& data-rawwidth=\&3208\& data-rawheight=\&2174\& class=\&origin_image inline-img zh-lightbox-thumb\& data-original=\&https:\u002F\\u002F20d6e9eb1ef6e29ba53c_r.png\&\u003E(原文首发于微信公众号:\u003Cb\u003E张铁蕾\u003C\u002Fb\u003E,)说Android端外推送比较烦,实际有两层意思:首先是说实现上比较麻烦,至今业界也没有找到一种完美的解决方案,Android程序员通常需要同时集成多家推送平台(如果有自己的端内推送,还要考虑与端内推送的配合)…&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F50\u002Fc3d385c4bcd0f73caed7f5_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Redis&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&源代码&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&算法&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&微爱CTO;微信公众号:tielei-blog;个人网址:&,&isFollowing&:false,&hash&:&a71c7f23e932ccaae143207e&,&uid&:384000,&isOrg&:false,&slug&:&zhtielei&,&isFollowed&:false,&description&:&老程序猿,全栈攻城狮,微爱CTO。\n分享技术干货,探讨个人成长。&,&name&:&张铁蕾&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzhtielei&,&avatar&:{&id&:&b08f1ba6c18efc6b6fdb68&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&zhangtielei&,&name&:&铁蕾的IT专栏&},&content&:&\u003Cp\u003E知乎的编辑器对于代码格式的编辑很不友好,建议到原文地址阅读:\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002Fposts\u002Fblog-redis-quicklist.html\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u002Fposts\u002Fb\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Elog-redis-quicklist.html\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E或者关注微信公众号(张铁蕾)查看精选文章。\u003C\u002Fp\u003E\u003Cimg data-rawheight=\&8718\& data-rawwidth=\&715\& src=\&https:\u002F\\u002Faa2ee55a14715b00deb85afc6e2f3dd1_b.png\& class=\&origin_image zh-lightbox-thumb\& width=\&715\& data-original=\&https:\u002F\\u002Faa2ee55a14715b00deb85afc6e2f3dd1_r.png\&\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T18:45:07+08:00&,&url&:&\u002Fp\u002F&,&title&:&Redis内部数据结构详解(5)——quicklist&,&summary&:&知乎的编辑器对于代码格式的编辑很不友好,建议到原文地址阅读:\u003Ca href=\&http:\\u002Fposts\u002Fblog-redis-quicklist.html\&\u003Ehttp:\\u002Fposts\u002Fblog-redis-quicklist.html\u003C\u002Fa\u003E 或者关注微信公众号(张铁蕾)查看精选文章。&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:1,&likesCount&:1},&next&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F50\u002Fc29a8b58e06ff7a133c943_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&程序员&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&编程学习&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&学习资料&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&微爱CTO;微信公众号:tielei-blog;个人网址:&,&isFollowing&:false,&hash&:&a71c7f23e932ccaae143207e&,&uid&:384000,&isOrg&:false,&slug&:&zhtielei&,&isFollowed&:false,&description&:&老程序猿,全栈攻城狮,微爱CTO。\n分享技术干货,探讨个人成长。&,&name&:&张铁蕾&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzhtielei&,&avatar&:{&id&:&b08f1ba6c18efc6b6fdb68&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&zhangtielei&,&name&:&铁蕾的IT专栏&},&content&:&\u003Cblockquote\u003E\u003Cp\u003E黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E这段描写出自《倚天屠龙记》第三十八回。\u003C\u002Fp\u003E\u003Cp\u003E“九阴神抓”本是《九阴真经》中的上乘武功,但当初梅超风夫妇由于拿到的《九阴真经》不完整,学不到里面的内功心法,硬是把这门上乘武功练到了邪路上,于是就成了“九阴白骨爪”。周芷若为求速成,也练就了这门邪功。\u003C\u002Fp\u003E\u003Cp\u003E但黄衫女子乃出身武林名门(相传是杨过和小龙女的后人),自然修炼的是正宗的《九阴真经》。虽然武功路数与周芷若本同属一脉,但更加“醇真深厚”,自然也更胜一筹。这是金庸武侠中“正宗”武功胜过“野路子”的一个典型案例。\u003C\u002Fp\u003E\u003Cp\u003E那么,这是否能够说明,“正宗”一定强于“野路子”呢?\u003C\u002Fp\u003E\u003Cp\u003E且慢!\u003C\u002Fp\u003E\u003Cp\u003E喜欢金庸武侠的朋友,可还记得《越女剑》中的阿青?\u003C\u002Fp\u003E\u003Cp\u003E阿青本是一名牧羊女,却在牧羊时巧遇一头会使竹棒的白猿。在与白猿的玩耍嬉闹中,她硬是悟得了高超的剑法,竟能以一人之力敌两千越甲!\u003C\u002Fp\u003E\u003Cp\u003E就是这样一个从野路子练出来的柔弱女子,即使按广大金庸迷的保守估计,她也能在整个金庸武侠图谱中至少排名前五!\u003C\u002Fp\u003E\u003Cp\u003E==============\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E做技术,犹如修习一门武功。\u003C\u002Fp\u003E\u003Cp\u003E历数我周围的技术牛人(牛不到一定程度的先不算),他们中既有名牌大学计算机科班毕业的,也有半路出家转行过来的。\u003C\u002Fp\u003E\u003Cp\u003E但他们都有一个共同特点:他们在遇到问题后,思考片刻,总是能一下子切中要害,在表达上也往往一语中的。这也包括那些平常不善言辞的程序员。反观那些“更一般”的程序员(其中不乏科班毕业的),他们经常很难抓住问题的本质,表达起来也总是说不到点子上。\u003C\u002Fp\u003E\u003Cp\u003E可见,“正宗”还是“野路子”,并不在出身。\u003C\u002Fp\u003E\u003Cp\u003E写到这里,我终于自己长出了一口气。我出身一个极普通的农民家庭,既不是书香门第,也不是技匠世家。记得在大学一年级的上机编程课上,我才发现自己原来根本不会用键盘打字。相比那些初中高中就把计算机玩得很溜的同学,我算野路子吗?\u003C\u002Fp\u003E\u003Cp\u003E好了,那“正宗”还是“野路子”,不在出身在什么呢?\u003C\u002Fp\u003E\u003Cp\u003E在于学习和思考的方法。\u003C\u002Fp\u003E\u003Cp\u003E据我观察,技术牛人的学习方法和思考方式,大体类似。\u003C\u002Fp\u003E\u003Cp\u003E思考方式,是个很难说清的东西。所以,本文我们重点来讨论讨论学习的方法。\u003C\u002Fp\u003E\u003Cp\u003E==============\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E面对一项新技术的时候,我们怎样去学习才能循序渐进,最终理解得深刻?\u003C\u002Fp\u003E\u003Cp\u003E让我们先把可供自学的资料列出来,分析一下:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003ETutorial(入门教程)。由该项技术的官网提供。通常是英文的。这份资料是给初次接触该项技术的人看的,一般是一步一步地教你完成某些例子。当我们说某项技术对于新手不太友好的时候,一般也是因为这项技术的Tutorial部分做得不够好。\u003C\u002Fli\u003E\u003Cli\u003ESpecification,简称Spec。这是集中体现该项技术的设计思想的东西,是高度抽象的描述。这个一般也是一份完备的、系统的描述,包含该项技术涉及到的方方面面。这部分资料在不同的地方叫法不同,在相对简单的技术项目中,也可能没有;在另一些情况下,这部分资料混杂在其它文档资料之中;它还可能以论文(paper)的形式出现。\u003C\u002Fli\u003E\u003Cli\u003EAPI Reference。大而全的API索引和文档,针对不同的语言接口可能提供多份。当我们使用这项技术进行编程的时候,API Reference自然是个离不开的、总是要不停去查询的一份资料。\u003C\u002Fli\u003E\u003Cli\u003E别人写的技术博客。质量良莠不齐,到底有没有价值,我们要学会去分辨。\u003C\u002Fli\u003E\u003Cli\u003E技术书籍。跟技术博客类似,质量有好有坏。稍后我们和技术博客放在一起来分析。\u003C\u002Fli\u003E\u003Cli\u003ESource Code。如果我们要学习的技术是开源的,那么很幸运,我们能得到源代码。这是一份终极资料。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E为了让这些概念表达无误,我接下来多举一些例子。\u003C\u002Fp\u003E\u003Ch4\u003EJava语言\u003C\u002Fh4\u003E\u003Cp\u003E从来没有接触过Java语言的人,要想开始自学Java,从哪里开始呢?可以从Oracle官方提供的Tutorial入手:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002Fjavase\u002Ftutorial\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EThe Java(TM) Tutorials\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E这份资料《The Java(TM) Tutorials 》,集中体现了Tutorial类型的资料的特点。它从最开始的编译和运行环境搭建说起,教你写出第一个Hello World,再用介绍的方式将Java各种语言特性(变量、类、泛型、Lambda表达式、JavaBeans,等等)进行讲解,同时还有对于JDK里常用API(集合类、多线程、IO等等)的介绍。\u003C\u002Fp\u003E\u003Cp\u003E对初学者而言,需要的就是这样一份资料。即使你手头没有任何Java的入门书籍,读完这样的一份资料之后,一个新手基本就可以开始使用Java来编程了。\u003C\u002Fp\u003E\u003Cp\u003E再看Spec:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002Fjavase\u002Fspecs\u002Fjls\u002Fse8\u002Fhtml\u002Findex.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EThe Java(R) Language Specification\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E这份文档,叫做《The Java(R) Language Specification》。是一份很典型的Spec,完备而规范。\u003C\u002Fp\u003E\u003Cp\u003E任何讲Java语法的资料,包括各种书籍和前面提到的Tutorial,都只能涉及部分。而这份Spec,如果你能读通的话,那么与Java语言特性有关的所有一切,你就再也不用求人了。\u003C\u002Fp\u003E\u003Cp\u003EJDK 8的API Reference:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002Fjavase\u002F8\u002Fdocs\u002Fapi\u002Findex.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EJava Platform SE 8\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E用Java语言编程的时候,我们需要不断查阅的就是这份API Reference。我们平常一般是通过IDE来快速查看某个接口的文档说明。\u003C\u002Fp\u003E\u003Ch4\u003EAndroid开发\u003C\u002Fh4\u003E\u003Cp\u003EAndroid针对新手的Tutorial类型的资料,官网上称为Training:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Ftraining\u002Findex.html\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u002Ft\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Eraining\u002Findex.html\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cimg src=\&http:\u002F\\u002F53a23e743b897dacddbf077_b.png\& data-rawwidth=\&1463\& data-rawheight=\&769\& class=\&origin_image zh-lightbox-thumb\& width=\&1463\& data-original=\&http:\u002F\\u002F53a23e743b897dacddbf077_r.png\&\u003E\u003Cbr\u003E\u003Cp\u003E这份资料是典型的Tutorial。它教你制作第一个Android App,并针对若干个主题进行一步一步的教学。\u003C\u002Fp\u003E\u003Cp\u003E下面这份资料在Android官网上被称为:API Guides。\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Fguide\u002Findex.html\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u002Fg\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Euide\u002Findex.html\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cimg src=\&http:\u002F\\u002F8ff5ec9e16b3e7a8db54f753c11efb67_b.png\& data-rawwidth=\&1467\& data-rawheight=\&778\& class=\&origin_image zh-lightbox-thumb\& width=\&1467\& data-original=\&http:\u002F\\u002F8ff5ec9e16b3e7a8db54f753c11efb67_r.png\&\u003E\u003Cbr\u003E\u003Cp\u003E它实际上是一份介于Tutorial和Spec之间的文档。它有很多Spec的特点,比如它介绍Android中的抽象的四大组件的概念,介绍资源尺寸的抽象(dp),介绍View层原理,等等。但是,跟前面看到的Java Spec相比,它没有那么规范和正式,描述也更随意一些,估计也算不上完备(但涉及到了Android技术的绝大部分)。\u003C\u002Fp\u003E\u003Cp\u003E当我们对Android中某项具体技术存疑,或是有争论的时候,我们就需要来翻翻这份文档。因此,它基本可以归入Spec类型。\u003C\u002Fp\u003E\u003Cp\u003E然后是Android SDK的API Reference:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Freference\u002Fpackages.html\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u002Fr\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Eeference\u002Fpackages.html\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E这份API Reference的质量并不高,描述上过于简略,甚至模糊不清,其可读性跟前面提到的JDK 8的API Reference完全不在一个水平上。这也是一些开源项目的通病,不重视接口文档。\u003C\u002Fp\u003E\u003Ch4\u003EiOS开发\u003C\u002Fh4\u003E\u003Cp\u003E苹果在iOS开发方面给出的文档是相当丰富的,这也是一个闭源系统做得好的地方。\u003C\u002Fp\u003E\u003Cp\u003EiOS开发的文档,很难区分出Tutorial和Spec这两个层面。它由很多文档组成,每个文档描述系统的某一方面。通常是在一个文档中,既有教学的部分,又有完备描述的部分。\u003C\u002Fp\u003E\u003Cp\u003E针对完全的新手入门的话,下面这个文档,算是真正的一个Tutorial:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Flibrary\u002Fios\u002Freferencelibrary\u002FGettingStarted\u002FDevelopiOSAppsSwift\u002Findex.html\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EStart Developing iOS Apps\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E其它各个文档也是介于Tutorial和Spec之间,更偏向Spec。比如:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Flibrary\u002Fios\u002Fdocumentation\u002FiPhone\u002FConceptual\u002FiPhoneOSProgrammingGuide\u002FIntroduction\u002FIntroduction.html\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EApp Programming Guide for iOS\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Flibrary\u002Fios\u002Ffeaturedarticles\u002FViewControllerPGforiPhoneOS\u002Findex.html\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EView Controller Programming Guide for iOS\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Flibrary\u002Fios\u002Fdocumentation\u002FWindowsViews\u002FConceptual\u002FViewPG_iPhoneOS\u002FIntroduction\u002FIntroduction.html\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EView Programming Guide for iOS\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Flibrary\u002Fmac\u002Fdocumentation\u002FCocoa\u002FConceptual\u002FCoreAnimation_guide\u002FIntroduction\u002FIntroduction.html\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ECore Animation Programming Guide\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Flibrary\u002Fios\u002Fdocumentation\u002FGeneral\u002FConceptual\u002FConcurrencyProgrammingGuide\u002FIntroduction\u002FIntroduction.html\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EConcurrency Programming Guide\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E然后是iOS的API Reference:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Freference\u002F\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttps:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u002Fref\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003Eerence\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&ellipsis\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E如前所述,这份API Reference的可读性非常高,比Android SDK的要强多了。很多前后相关的概念,在这份API Reference的描述中,都有体现。\u003C\u002Fp\u003E\u003Cp\u003E当然,除了\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E之外,iOS的文档也都可以通过XCode取到。\u003C\u002Fp\u003E\u003Ch4\u003ERedis\u003C\u002Fh4\u003E\u003Cp\u003ERedis的Tutorial是我见过的最好的Tutorial,它对初学者非常友好,不仅能读,还能执行。\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Ftry.redis.io\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ETry Redis\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cimg src=\&http:\u002F\\u002F9bb3fc54c672c37ea8fe2_b.jpg\& data-rawwidth=\&1164\& data-rawheight=\&580\& class=\&origin_image zh-lightbox-thumb\& width=\&1164\& data-original=\&http:\u002F\\u002F9bb3fc54c672c37ea8fe2_r.jpg\&\u003E\u003Cbr\u003E\u003Cp\u003ERedis的Spec举例:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Fredis.io\u002Ftopics\u002Fprotocol\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ERedis Protocol specification\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Fredis.io\u002Ftopics\u002Fcluster-spec\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ERedis Cluster Specification\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Ca class=\& wrap external\& href=\&http:\u002F\\u002F?target=https%3A\\u002Fsripathikrishnan\u002Fredis-rdb-tools\u002Fwiki\u002FRedis-RDB-Dump-File-Format\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ERedis RDB Dump File Format\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003ERedis的Commands Reference:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Fredis.io\u002Fcommands\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ECommand reference ?EUR“ Redis\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Ch4\u003ETCP\u002FHTTP\u003C\u002Fh4\u003E\u003Cp\u003E网络协议与前面的都不同,它不是一个实现,而是一种标准。\u003C\u002Fp\u003E\u003Cp\u003E网络协议的Spec文档很明显,就是它们对应的RFC。如果你的工作经常涉及到使用某个网络协议,恐怕就需要找来RFC通读一遍了。\u003C\u002Fp\u003E\u003Cbr\u003E==============\u003Cbr\u003E\u003Cp\u003E再来说一下技术博客和技术书籍。\u003C\u002Fp\u003E\u003Cp\u003E现在网上的技术文章空前繁荣,想读都读不过来。胡峰同学在他的微信公众号“瞬息之间”上,发过一篇文章《技术干货的选择性问题》,讨论的就是技术人员在当前技术文章爆炸的情况下如何取舍的问题。\u003C\u002Fp\u003E\u003Cp\u003E在这里,我们从另一个角度来讨论一下这个问题。如果一篇技术文章,仅仅是对于所涉及技术的官方文档(Tutorial或Spec)的复述,甚至只是个翻译,那么就价值不高。换句话说,如果我们能通过阅读官方文档学到同样的知识,那为什么要看你写的技术文章呢?官方文档自然更权威,直接阅读它能确保不会遗漏重要的东西。\u003C\u002Fp\u003E\u003Cp\u003E那什么样的技术文章才有价值呢?大概可以说(未必那么准确),那些包涵了实践经验的,能将各个技术点综合起来产生思考,从而给人以启迪的。简单来说,就是有深度的。\u003C\u002Fp\u003E\u003Cp\u003E当然,技术书籍也大体如此。\u003C\u002Fp\u003E\u003Cbr\u003E==============\u003Cbr\u003E\u003Cp\u003E我们回过头来再看一下,各个学习资料之间的层次结构。\u003C\u002Fp\u003E\u003Cimg src=\&http:\u002F\\u002F119efdc651aeb2fab538255f_b.png\& data-rawwidth=\&2566\& data-rawheight=\&1574\& class=\&origin_image zh-lightbox-thumb\& width=\&2566\& data-original=\&http:\u002F\\u002F119efdc651aeb2fab538255f_r.png\&\u003E\u003Cp\u003E每当我们接触一项新的技术的时候,我们都要把手头的资料按照类似的这样一个金字塔结构进行分类。如果我们阅读了一些技术博客和技术书籍,那么也要清楚地知道它们涉及到的是金字塔中的哪些部分。\u003C\u002Fp\u003E\u003Cp\u003E最开始,一般读完Tutorial之后,就基本能上手做一些开发工作了。然后一边开发,一边查阅API Reference。注意,从这时候起,你的老板就开始向你付工资了,因为你的工作已经能够产出成果了。\u003C\u002Fp\u003E\u003Cp\u003E但是,工作一段时间之后,我们发现,似乎身边的技术牛人学东西都比较快,而且在很短的时间内就能对某项新技术达到很深的理解。这是为什么呢?\u003C\u002Fp\u003E\u003Cp\u003E这并不是因为技术牛人阅读技术资料阅读得快,而是他们知道阅读正确的资料,从而很快能达到知识金字塔更高的一层。\u003C\u002Fp\u003E\u003Cp\u003E我见过的很多技术牛人,他们如果不是把一项技术至少理解到Spec那个层次,他们是不敢随便写代码的。相反另一些人则从网上随意拷贝代码,并在自己不能完全理解的情况下用到项目中去。技术牛人们当然也参考网上的代码,但他们通常会确保它的每一部分都能安放在知识金字塔的某一部分,他们不容许那种不属于任何体系的知识孤岛的出现。\u003C\u002Fp\u003E\u003Cp\u003E我们现在可以这样总结,技术的“野路子”,其实是知识结构的不完整和不系统造成的一种状态。只有当你冲破知识金字塔层层的障碍,迈向更高层次的时候,老板才开始向你付高价。\u003C\u002Fp\u003E\u003Cp\u003E==============\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E我们的大脑好比内存。\u003C\u002Fp\u003E\u003Cp\u003E既然是内存,就装不下所有的知识。但应该能装下对于知识的索引,否则我们便没法工作了。\u003C\u002Fp\u003E\u003Cp\u003E那么,这里就有一个选择性的问题:我们选择哪部分知识加载到“内存”里呢?\u003C\u002Fp\u003E\u003Cp\u003E显然,应该优先选择重要的,对我们最有用的信息。\u003C\u002Fp\u003E\u003Cp\u003E对于那些最核心的技术,我们应该做到:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E通读Spec。读完就不再困惑。\u003C\u002Fli\u003E\u003Cli\u003E重要部分的API Reference要通读。里面包含了很多跟实现有关的信息。\u003C\u002Fli\u003E\u003Cli\u003E如果工作需要,还可能需要读到Source Code。特别是对于平常一直在使用的SDK,不一定从头到尾把源码读通,这样工作量太大且效率不高,但\u003Cstrong\u003E一定要把你的开发环境设置成一点击某个调用的方法就能跳转进源码实现\u003C\u002Fstrong\u003E。只有这样,你才能把平常开发的时间利用起来,随时随刻都点过去看源码。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E对于剩下的知识里80%的部分,应该至少理解到Spec层次。只有这样,我们才能游刃有余地去使用它。\u003C\u002Fp\u003E\u003Cp\u003E通读重要的Spec,在很多情况下,其实还是很有难度的。这需要毅力,和一点点英语基础。\u003C\u002Fp\u003E\u003Cp\u003E按本文前面提到的例子,做Java的人有谁读过Java Spec?做Android的人有谁把\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E上的API Guides都能通读下来?而做iOS的人,\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E上的各个Programming Guide又完整地读过几个?对于经常调用的SDK,你会有计划地去通读其中重要部分的API Reference吗?\u003C\u002Fp\u003E\u003Cp\u003E能够把这一套做下来的,有可能不成为技术牛人吗?\u003C\u002Fp\u003E\u003Cbr\u003E==============\u003Cbr\u003E\u003Cp\u003E到了文章最后了,总感觉还有些意犹未尽,脑海中似乎有些东西还是没有表达出来,也不确定本文描述的学习方式是不是适用于每位读者。仔细想想也难怪,学习本来就是一个复杂的问题,每个人并不是完全一样的套路。\u003C\u002Fp\u003E\u003Cp\u003E但是,不管本文介绍的方法是“正宗”的路子,还是属于“野路子”,我在这里想要强调的一点是很明确的,那就是:要把知识梳理成系统的结构,要让头脑中的知识层次清楚,为此,我们需要阅读恰当的东西,需要不断地练习,需要克服种种困难。\u003C\u002Fp\u003E\u003Cp\u003E成长没有捷径可走。需要的是一个一个坚实的突破。\u003C\u002Fp\u003E\u003Cp\u003E(完)\u003C\u002Fp\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T22:48:08+08:00&,&url&:&\u002Fp\u002F&,&title&:&技术的正宗与野路子&,&summary&:&黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙。这段描写出自《倚天屠龙记》第三十八回。“九阴神抓”本是《九阴真经》中的上乘武功,但当初梅超风夫妇由于拿到的《九…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:3,&likesCount&:2}},&annotationDetail&:null,&commentsCount&:0,&likesCount&:2,&FULLINFO&:true}},&User&:{&zhtielei&:{&isFollowed&:false,&name&:&张铁蕾&,&headline&:&老程序猿,全栈攻城狮,微爱CTO。\n分享技术干货,探讨个人成长。&,&avatarUrl&:&https:\u002F\\u002F50\u002Fb08f1ba6c18efc6b6fdb68_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&zhtielei&,&bio&:&微爱CTO;微信公众号:tielei-blog;个人网址:&,&hash&:&a71c7f23e932ccaae143207e&,&uid&:384000,&isOrg&:false,&description&:&老程序猿,全栈攻城狮,微爱CTO。\n分享技术干货,探讨个人成长。&,&badge&:{&identity&:null,&bestAnswerer&:null},&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzhtielei&,&avatar&:{&id&:&b08f1ba6c18efc6b6fdb68&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}},&Comment&:{},&favlists&:{}},&me&:{},&global&:{&experimentFeatures&:{&ge3&:&ge3_9&,&ge2&:&ge2_1&,&nwebStickySidebar&:&sticky&,&androidPassThroughPush&:&getui&,&newMore&:&new&,&liveReviewBuyBar&:&live_review_buy_bar_2&,&liveStore&:&ls_a2_b2_c1_f2&,&searchHybridTabs&:&without-tabs&,&isOffice&:&false&,&homeUi2&:&default&,&answerRelatedReadings&:&qa_recommend_with_ads_and_article&,&remixOneKeyPlayButton&:&headerButton&,&asdfadsf&:&asdfad&,&qrcodeLogin&:&qrcode&,&newBuyBar&:&livenewbuy3&,&isShowUnicomFreeEntry&:&unicom_free_entry_off&,&newMobileColumnAppheader&:&new_header&,&zcmLighting&:&zcm&,&favAct&:&default&,&appStoreRateDialog&:&close&,&mobileQaPageProxyHeifetz&:&m_qa_page_nweb&,&iOSNewestVersion&:&4.2.0&,&default&:&None&,&wechatShareModal&:&wechat_share_modal_show&,&qaStickySidebar&:&sticky_sidebar&,&androidProfilePanel&:&panel_b&,&nwebWriteAnswer&:&default&}},&columns&:{&next&:{},&zhangtielei&:{&following&:false,&canManage&:false,&href&:&\u002Fapi\u002Fcolumns\u002Fzhangtielei&,&name&:&铁蕾的IT专栏&,&creator&:{&slug&:&zhtielei&},&url&:&\u002Fzhangtielei&,&slug&:&zhangtielei&,&avatar&:{&id&:&f4ffaceacd&,&template&:&https:\u002F\\u002F{id}_{size}.jpeg&}}},&columnPosts&:{},&columnSettings&:{&colomnAuthor&:[],&uploadAvatarDetails&:&&,&contributeRequests&:[],&contributeRequestsTotalCount&:0,&inviteAuthor&:&&},&postComments&:{},&postReviewComments&:{&comments&:[],&newComments&:[],&hasMore&:true},&favlistsByUser&:{},&favlistRelations&:{},&promotions&:{},&draft&:{&titleImage&:&&,&titleImageSize&:{},&isTitleImageFullScreen&:false,&canTitleImageFullScreen&:false,&title&:&&,&titleImageUploading&:false,&error&:&&,&content&:&&,&draftLoading&:false,&globalLoading&:false,&pendingVideo&:{&resource&:null,&error&:null}},&drafts&:{&draftsList&:[],&next&:{}},&config&:{&userNotBindPhoneTipString&:{}},&recommendPosts&:{&articleRecommendations&:[],&columnRecommendations&:[]},&env&:{&edition&:{},&isAppView&:false,&appViewConfig&:{&content_padding_top&:128,&content_padding_bottom&:56,&content_padding_left&:16,&content_padding_right&:16,&title_font_size&:22,&body_font_size&:16,&is_dark_theme&:false,&can_auto_load_image&:true,&app_info&:&OS=iOS&},&isApp&:false},&message&:{&newCount&:0},&pushNotification&:{&newCount&:0}}

我要回帖

更多关于 安卓第三方推送 的文章

 

随机推荐