还是找不到yngc888目前,正常的wwWyngc888com介入地止啊

&p&给大家推荐三个我自己觉得好得不行的东西,这也是我给家人极力推荐的,有益健康,这年头儿,保养身体比什么都重要,特别是上了岁数的父母,身体不出现大问题就是给子女挣钱呀!&/p&&p&前段时间给我家极力推荐了一个“罐子”,它叫做“能量罐”(就是普通陶瓷做成的,建议买厚一些的,薄的不舒服,某宝上可以搜到,可以只买几个大点的,没必要买一套),如果你身边有拔罐用的玻璃罐也可以用,但没有陶瓷的舒服。它是这样子的:&/p&&figure&&img data-rawwidth=&1707& data-rawheight=&1280& src=&https://pic3.zhimg.com/v2-2fe34d69dfa2852d3cba_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1707& data-original=&https://pic3.zhimg.com/v2-2fe34d69dfa2852d3cba_r.jpg&&&/figure&&br&&p&我主要用它来刮头、刮胳膊腿儿,这些地方都可以自己来操作,挂完之后特别舒服,并且对健康是极好的。&/p&&p&比如刮头的时候,你会感到有的地方特别疼,大部分人疼的地方很多,因为我们头上的肌肉、筋膜非常僵,并且有很多结节,就像很多“蚯蚓”一样纠纠结结,因为你几十年都没有给自己的头部的组织放松过,而每天又要动脑思考、焦虑、压力大!&/p&&p&这种方法类似“梳头养生”,只但是更彻底,更简单粗暴,你在刮完之后会立刻感到头部热热的,头脑清楚,身子舒坦,但不乏会有疼痛并会残留几天,类似刮痧过。&/p&&p&这种方法对缓解疲劳、养生、头晕、睡眠不好、脱发等会有帮助,不是有说做一次头部按摩相当于做十次足疗嘛。&/p&&p&使用的方法就是用这个罐儿的罐口在头上来回刮,每个部位均匀一些,头顶,头两侧,头后都要来回刮,每个区在刮的时候感觉还会不一样,有的地方酸爽,有的地方疼爽,总之都是爽!&/p&&figure&&img data-rawheight=&222& src=&https://pic3.zhimg.com/v2-dbfa73e25d2_b.jpg& data-rawwidth=&811& class=&origin_image zh-lightbox-thumb& width=&811& data-original=&https://pic3.zhimg.com/v2-dbfa73e25d2_r.jpg&&&/figure&&p&&b&第二个小东西给大家推荐的是泡沫轴。&/b&&/p&&p&这个我之前提到过很多了,看过我之前文章的知友肯定很熟悉了。泡沫轴在是一个自我放松肌肉的神器,可以在主动运动时放松,比单纯的被动按摩效果好很多,并且可以随时随地,比男朋友可靠谱多了!&/p&&figure&&img data-rawheight=&255& src=&https://pic4.zhimg.com/v2-d89aedfe81e2341dfe6ce03_b.jpg& data-rawwidth=&549& class=&origin_image zh-lightbox-thumb& width=&549& data-original=&https://pic4.zhimg.com/v2-d89aedfe81e2341dfe6ce03_r.jpg&&&/figure&&p&泡沫轴可以放松身体大部分肌肉,对腰痛、颈痛、膝关节疼痛都会有很好的帮助,我之前有拍过很多关于使用泡沫轴的小视频,你可以查看下。&/p&&p&&b&也有写过一篇文章,你可以参考:&/b&&/p&&p&&b&&a href=&https://www.zhihu.com/question//answer/& class=&internal&&李明威:泡沫轴是什么?&/a&&/b&&/p&&p&&br&&/p&&p&&b&第三个给大家推荐,瑜伽球,平时上班坐着用。&/b&&/p&&p&我表示上班一直在做瑜伽球办公,包括现在,已经离不开,我最大直接感受是,我坐一天瑜伽球腰也没事儿,但坐椅子根本不行,腰酸,毕竟现在大家每天一坐就是六个小时八个小时甚至十个小时的,多好的腰时间久了都受不了!&/p&&p&坐瑜伽球可以很好的保护腰椎,它可以很好地激活腰椎深层的稳定肌群,要注意的是,在坐的时候,我们可以用脚后跟在下面顶着球,这样可以避免腰部发力过多太劳累以及可以坐稳。&/p&&p&你可以去尝试开始,试几天后跟自己之前对比,你会发现腰舒服很多。&/p&&p&下图当中那个球已经被我坐了快2年了,都被我坐成椭圆了...&/p&&figure&&img data-rawwidth=&1440& data-rawheight=&1080& src=&https://pic2.zhimg.com/v2-6e5d140cf88dacc2fcfff6c_b.jpg& class=&origin_image zh-lightbox-thumb& width=&1440& data-original=&https://pic2.zhimg.com/v2-6e5d140cf88dacc2fcfff6c_r.jpg&&&/figure&&br&这么好用的东西,你要分享给谁?
给大家推荐三个我自己觉得好得不行的东西,这也是我给家人极力推荐的,有益健康,这年头儿,保养身体比什么都重要,特别是上了岁数的父母,身体不出现大问题就是给子女挣钱呀!前段时间给我家极力推荐了一个“罐子”,它叫做“能量罐”(就是普通陶瓷做成的…
&p&给亲分享一篇 蚂蚁金服技术专家 清英 的一篇文——《如何在三年内快速成长为一名技术专家》,希望对亲有所帮助!&/p&&p&工作前三年是职业生涯中成长最快的几年,在这段时间里你会充满激情,做事专注,也容易养成良好的习惯。在我们公司有些同学在前三年中就快速成为某一个领域的技术专家,有些同学也可能止步不前。本文和大家一起探讨下如何在三年内快速成长为一名技术专家。&/p&&p&&b&目录&/b&&/p&&p&&b&学习方法&/b&&/p&&ul&&li&1:掌握良好的学习心态&/li&&li&2:掌握系统化的学习方法&/li&&li&3:知识如何内化成能力&/li&&li&4:广度和深度的选择&/li&&/ul&&p&&b&实战技巧&/b&&/p&&ul&&li&1:你需要学会的编码习惯&/li&&li&2:在业务团队做开发如何成长&/li&&/ul&&p&&br&&/p&&h2&&b&掌握良好的学习心态&/b&&/h2&&h2&空杯心态&/h2&&p&首先要有空杯的学习心态,而不是傲娇自满,故步自封,空杯子才可以装下更多的东西。首先要学会取百家之长,带着欣赏的眼光看团队的同事或学校的同学,欣赏每位同事或同学的优点,然后吸取他们的优点,每个同事都有其擅长的能力,比如有的同事技术能力强,那么可以观察下他如何学习的(或者找他请教学习方法),有的同学擅长解决线上问题,那么观察他是如何解决线上问题的,解决思路是什么?如果他解决不了时,他是如何寻求帮助。有的同学擅长使用IDE或MAC的快捷键,那么可以向他学习提高工作效率。有的同学能快速理解业务知识,观察他是如何做到的,自己如何达到他的程度。沟通能力,解决问题能力以及规划能力都可以向同事学习。&/p&&h2&挑战权威&/h2&&p&从书上看到一个知识点,或者从别人那里听到一个知识点,一定要去挑战和质疑这个知识点的正确性,否则学到的知识点可能是错误的。先用逻辑思维推测下,再实战检测下,一定要记住实践是检验真理的唯一标准。比如同事说这个SQL加这个索引是最快的,首先要思考同事的结论是如何得出的,是靠历史经验还是测试过,如果我们没有经验,就加上这个索引跑下SQL,看看执行计划和执行时间,再换下其他索引试试会不会更快。依次类推,并发一定比串行快吗?无锁一定比加锁快吗? 很多结论都是在特定的场景下才会产生的,一定要自己亲手实践验证下。&/p&&h2&坚持学习&/h2&&p&有的同学可能工作了五年,但是学习的时间可能一年都不到。学技术不能急于求成,只要学习方法正确,量变一定会引起质变。我在大学刚学JAVA时,怎么都学不会,但是坚持学习了几个月,每天看张老师的JAVA视频教学,买书按照书里的代码一行一行的敲代码,白天睡觉,晚上学习和写代码,写到宿舍关灯时就去避风塘呆一晚上,早上6点钟回宿舍睡觉,学到一定时间后,突然恍然大悟,才入了门。&/p&&p&在工作中,我曾经花了一个月的时间学习AOP的实现原理,学习了各种方式来实现AOP的原理,并写了几种实现方式的代码,虽然花的时间很多,但是到现在仍记忆犹新,对于排查问题和学习其他知识都非常有帮助。&/p&&p&要做到坚持学习,学习的环境非常重要。如果你想学,但是又不在学习状态,可以考虑换个学习环境,我经常会去星巴克看书和学习。我听说有的同事会周末抽一天去大学教师上自习。&/p&&h2&把事做精&/h2&&p&&b&对自己要求越高,进步越快&/b&。要有强烈的把事情做完美的心态,我刚开始工作的时候,总是快而不精,做事做的不够细致,总希望快速拿出结果证明自己,但是反而证明不了什么,技术能力也得不到提升,缺少技术亮点,在团队中也没什么影响力,后面就开始锻炼一次就把事情做对的心态和方法。我观察过,很多人都擅长快速做事情,但是把事情做好做精致的人会比较少,但是结果却是**在精益求精的路上才会快速提高自己的能力**。比如用100行代码实现的功能,思考下是否可以用10行来实现,以便于降低运维成本,提高下次的编码效率。引用GUAVA等类库,提取公共方法,和使用JDK8新特性等。系统的方法压测过后,单机只能承受1700QPS,可以思考和实践能否优化下程序提高QPS,减少服务器数量。&/p&&p&把事情做精,一定是要强迫自己多花心思多花时间在这件事情上。有位技术牛人给我分享了一个心得,我觉得说的非常好,老板给你布置了一个任务,**你要花百分之150的精力做到100分,这样在老板那里你就能拿到80分或者60分**。&/p&&h2&&b&掌握系统化的学习方法&/b&&/h2&&p&如果学习到的知识不成体系,那么遇到问题时就会非常难解决。有些同学会出现这些情况,比如编码时遇到问题百度搜索,如果百度上找不到答案,这个问题就解决不了。再比如,在开发中要用到某个技术点,就学习下API,程序调通后就不再深入研究,浅尝辄止,如果程序遇到其他问题也不知道如何解决。&/p&&p&以上情况我认为叫**点状学习**。遇到一个问题,解决一个问题,需要一项技术,学习一项技术。那么如何由点到面,由面到体,形成系统化学习呢。&/p&&p&首先要确定学习的知识领域,需要达成的学习目标,针对目标制定学习计划,就像你要写一本书一样,先把目录写出来,然后根据目录上的知识点逐步去学习,最后把这些知识点关联起来,形成一个系统化的知识体系。学习的时候,可以制定一个计划,以周为单位,比如第一周学什么,第二周学什么。&/p&&p&比如我最近在学习人工智能,学习步骤是:&/p&&ul&&li&1: 高数基础知识:线性代数,微积分和统计学。最近在打德州扑克时,我也会用统计学里的知识计算下输赢的概率。&/li&&li&2: 人工智能基础:买几本书人工智能的基础书籍,如《机器学习基础教程》《Python机器学习》&/li&&li&3:框架:TensorFlow等。&/li&&li&4:实战:在工作中找到一个应用场景,把学到的知识运用进去。&/li&&/ul&&h2&&b&知识如何内化成能力&/b&&/h2&&p&作家格拉德威尔在《异类》一书中指出,1万小时的锤炼是任何人从平凡变成世界级大师的必要条件。1万小时有多久?每天学习10小时,需要大约三年。但是很多人都工作了五年甚至更长,但是为什么成为世界级大师的却非常少。读者可以先自己思考下这个问题。接下来谈谈我的看法。&/p&&p&成长必须经历一个步骤,就是把知识内化成能力。**知识是用脑记住的,能力是用手练习出来的**。在工作的几年里,我们可能看过很多书,听过很多技术讲座和视频,但是通过听和看只是让你能记住这些知识,这些知识还不能转换成你的能力。&/p&&p&听和看只是第一步,更重要的是实践,通过刻意练习把听到和看到的知识内化成你的能力。&/p&&p&刻意练习,就是有目的的练习,先规划好,再去练习。首先给自己定一个目标,目标可以有效的引导你学习,然后使用3F练习法:&/p&&ul&&li&1: 专注(Focus),专注在眼前的任务上,在学习过程中保持专注,可以尝试使用番茄工作法。&/li&&li&2:反馈(Feedback),意识到自己的不足,学习完之后进行反思,思考下自己哪些方面不足,为什么不足,&/li&&li&3: 修正(Fix),改进自己的不足。&/li&&/ul&&p&不停的练习和思考可以改变大脑结构,大脑像肌肉一样,挑战越大,影响越大,学习更高效,并且也会产生突破性。&/p&&h2&&b&广度和深度的选择&/b&&/h2&&p&技术人员的学习路径有两个维度,深度和广度。很多程序员都有这个疑问,是先深后广,还是先广后深呢?&/p&&p&通过这么多年的学习和思考,我的建议先深后广,因为当技术学到一定深度后,就会有触类旁通的能力,自己掌握的广度也自然有了深度。但是在实际学习过程中,深度和广度相互穿插着学习,比如学习并发编程时,首先学习JDK源码,然后学进去之后,开始看JVM源码,最后看CPU架构,在技术点逐渐深度研究的过程中,广度也得到了完善。&/p&&p&所以无论哪种学习方式,学习态度才是最重要的,在广度学习的时候有深入研究的态度就能达到一定的深度,在深度学习的时候,主动学习相关的技术点,广度也得到拓宽。&/p&&h2&&b&你需要学会的编码习惯&/b&&/h2&&p&程序员应该学会通过技术的手段来提高效率。几个常用的手段是使用工具,快捷键和编写脚本。&/p&&ul&&li&1. 使用各种工具&/li&&/ul&&p&技术人员电脑尽量用MAC,使用命令行效率一定比在像素中找一个10*10像素的按钮更快。IDE用IDEA,比Eclipse更智能。命令行工具用iTerm和IDEA里的Terminal。写文章用MAC的客户端工具MacDown,左边编写,右边展示,比Word等工具方便快速很多。有时候我还会用按键精灵里配置脚本需要解决工作问题,比如通过点击我们的系统,来执行任务。这样的工具很多,只要能提高工作效率的工具,大家都可以尝试使用。&/p&&ul&&li&2. 使用快捷键&/li&&/ul&&p&MAC,IDEA和Eclipse有很多快捷键都要学会使用,比如在MAC命令行中通过idea .快速打开工程,通过open . 快速的打开文件夹,把IDEA里通过快捷键把一段代码抽成一个单独的方法,快速生成getter setter方法。&/p&&ul&&li&3. 用脚本写工具&/li&&/ul&&p&当我们用人工的方式做一件重复性很强的事情,首先要考虑使用工具来帮我们自动完成,如果没有类似工具,可以自己写个脚本来实现,这样除了能快速解决问题,还能提高自己的技术能力。&/p&&p&比如,我经常要在两个maven仓库发布jar包,我就写了个脚本来实现jar包的发布,deploy.sh代码如下:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-f795a223dfccc7e6542e6_b.jpg& data-caption=&& data-rawwidth=&429& data-rawheight=&145& class=&origin_image zh-lightbox-thumb& width=&429& data-original=&https://pic3.zhimg.com/v2-f795a223dfccc7e6542e6_r.jpg&&&/figure&&h2&&b&在业务团队做开发如何成长&/b&&/h2&&p&我一直在业务团队中做开发,在业务团队最主要的提高的能力是业务抽象和架构能力,通过业务场景,不断思考如何通过合理的架构和业务抽象能快速支持业务,降低运维成本。同时在这个过程中锻炼技术能力,比如写一些技术框架来快速支持业务,做到技术驱动业务。&/p&&p&&b&可配置化的方式支持业务&/b&&/p&&p&设计业务的领域模型,把不随着业务逻辑变化的领域模型做成系统能力,把随着业务逻辑变化功能,做成可配置化,上一个新业务,通过配置的方式或少量开发就能支持。&/p&&p&在做客户后台功能时,由于需要展示的数据种类非常多,每种数据展示可能需要花费几天的时间,所以设计了一个通用的技术框架,实现了通过配置化的方式展示各种数据。&/p&&p&&b&写框架解决业务问题&/b&&/p&&p&我在上家公司经常做一些CRUD的业务功能,我就自己开发了一个快速做CRUD的框架&a href=&//link.zhihu.com/?target=https%3A//github.com/areyouok/utils& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&jdbcutil&/a&,通过配置实体生成SQL语句,实现了子类只要继承父类,就自动拥有CRUD的能力。后面还写过生成CRUD页面代码的程序。&/p&&p&目前我们团队在做的&a href=&//link.zhihu.com/?target=http%3A//ifeve.com/titan-module/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TITAN框架&/a&通过模块化开发的方式,解决易变的业务系统在多人开发时遇到的问题。&/p&&p&&b&技术驱动业务&/b&&/p&&p&在业务团队,一定要不断的思考如何利用技术来支持快速支持业务,配置化是一种思路,但是有些功能配置复杂度比较高,配置加验证的工作量,可能需要一个星期的时间,那么能不能减少人工配置,实现系统自动化配置,于是可以研究下人工智能,通过人工智能的方式实现,系统告诉人需要配置哪些东西,然后交给人来进行确认,这样可以大大减少人工成本,更快的支持业务。&/p&&p&&br&&/p&&p&&b&更多技术干货敬请关注云栖社区知乎机构号:&a href=&https://www.zhihu.com/org/a-li-yun-yun-qi-she-qu-48& class=&internal&&阿里云云栖社区 - 知乎&/a&&/b&&/p&
给亲分享一篇 蚂蚁金服技术专家 清英 的一篇文——《如何在三年内快速成长为一名技术专家》,希望对亲有所帮助!工作前三年是职业生涯中成长最快的几年,在这段时间里你会充满激情,做事专注,也容易养成良好的习惯。在我们公司有些同学在前三年中就快速成…
&figure&&img src=&https://pic2.zhimg.com/v2-369d5aa860ed824a54d708_b.jpg& data-rawwidth=&1185& data-rawheight=&731& class=&origin_image zh-lightbox-thumb& width=&1185& data-original=&https://pic2.zhimg.com/v2-369d5aa860ed824a54d708_r.jpg&&&/figure&&p&这期是 HenCoder 自定义绘制的第 1-4 期:Canvas 对绘制的辅助——范围裁切和几何变换。&/p&&p&之前的内容在这里: &/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&HenCoder Android 开发进阶 自定义 View 1-1 绘制基础&/a& &/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&HenCoder Android 开发进阶 自定义 View 1-2 Paint 详解&/a& &/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&HenCoder Android 开发进阶 自定义 View 1-3 文字的绘制&/a&&/p&&p&如果你没听说过 HenCoder,可以先看看这个: &/p&&p&&a href=&https://zhuanlan.zhihu.com/p/& class=&internal&&HenCoder:给高级 Android 工程师的进阶手册&/a&&/p&&h2&&b&简介&/b&&/h2&&p&一图胜千言,一视频胜千图,走你:&/p&&a class=&video-box& href=&https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/227392& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic3.zhimg.com/v2-52da62eb7f30455ceb59e.jpg& data-lens-id=&227392&&
&img class=&thumbnail& src=&https://pic3.zhimg.com/v2-52da62eb7f30455ceb59e.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/227392&/span&
&p&&br&&/p&&h2&&b&1 范围裁切&/b&&/h2&&p&范围裁切有两个方法: clipRect() 和 clipPath()。裁切方法之后的绘制代码,都会被限制在裁切范围内。&/p&&h2&&b&1.1 clipRect()&/b&&/h2&&p&使用很简单,直接应用:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.clipRect(left, top, right, bottom);
canvas.drawBitmap(bitmap, x, y, paint);
&/code&&/pre&&/div&&figure&&img src=&https://pic2.zhimg.com/v2-b120a1e1daafd75ed6a71e_b.jpg& data-rawwidth=&1754& data-rawheight=&974& class=&origin_image zh-lightbox-thumb& width=&1754& data-original=&https://pic2.zhimg.com/v2-b120a1e1daafd75ed6a71e_r.jpg&&&/figure&&p&记得要加上 Canvas.save() 和 Canvas.restore() 来及时恢复绘制范围,所以完整代码是这样的:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
canvas.clipRect(left, top, right, bottom);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&h2&&b&1.2 clipPath()&/b&&/h2&&p&其实和 clipRect() 用法完全一样,只是把参数换成了 Path ,所以能裁切的形状更多一些:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
canvas.clipPath(path1);
canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
canvas.restore();
canvas.save();
canvas.clipPath(path2);
canvas.drawBitmap(bitmap, point2.x, point2.y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic2.zhimg.com/v2-b53fdf38bc1c_b.jpg& data-rawwidth=&1622& data-rawheight=&802& class=&origin_image zh-lightbox-thumb& width=&1622& data-original=&https://pic2.zhimg.com/v2-b53fdf38bc1c_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&2 几何变换&/b&&/h2&&p&几何变换的使用大概分为三类:&/p&&ol&&li&使用 Canvas 来做常见的二维变换;&/li&&li&使用 Matrix 来做常见和不常见的二维变换;&/li&&li&使用 Camera 来做三维变换。&/li&&/ol&&h2&&b&2.1 使用 Canvas 来做常见的二维变换:&/b&&/h2&&h2&&b&2.1.1 Canvas.translate(float dx, float dy) 平移&/b&&/h2&&p&参数里的 dx 和 dy 表示横向和纵向的位移。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
canvas.translate(200, 0);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic1.zhimg.com/v2-cdff8ba769d19af9a20ff6c8a660dc67_b.jpg& data-rawwidth=&2024& data-rawheight=&890& class=&origin_image zh-lightbox-thumb& width=&2024& data-original=&https://pic1.zhimg.com/v2-cdff8ba769d19af9a20ff6c8a660dc67_r.jpg&&&/figure&&blockquote&好吧这个从截图并不能看出什么,那你就用心去感受吧&/blockquote&&h2&&b&2.1.2 Canvas.rotate(float degrees, float px, float py) 旋转&/b&&/h2&&p&参数里的 degrees 是旋转角度,单位是度(也就是一周有 360° 的那个单位),方向是顺时针为正向; px 和 py 是轴心的位置。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
canvas.rotate(45, centerX, centerY);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic2.zhimg.com/v2-0efe22050f_b.jpg& data-rawwidth=&1834& data-rawheight=&1030& class=&origin_image zh-lightbox-thumb& width=&1834& data-original=&https://pic2.zhimg.com/v2-0efe22050f_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&2.1.3 Canvas.scale(float sx, float sy, float px, float py) 放缩&/b&&/h2&&p&参数里的 sx sy 是横向和纵向的放缩倍数; px py 是放缩的轴心。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
canvas.scale(1.3f, 1.3f, x + bitmapWidth / 2, y + bitmapHeight / 2);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic4.zhimg.com/v2-8b295a7adf_b.jpg& data-rawwidth=&1171& data-rawheight=&624& class=&origin_image zh-lightbox-thumb& width=&1171& data-original=&https://pic4.zhimg.com/v2-8b295a7adf_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&2.1.4 skew(float sx, float sy) 错切&/b&&/h2&&p&参数里的 sx 和 sy 是 x 方向和 y 方向的错切系数。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
canvas.skew(0, 0.5f);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic3.zhimg.com/v2-a886ee0ce2a27b_b.jpg& data-rawwidth=&930& data-rawheight=&474& class=&origin_image zh-lightbox-thumb& width=&930& data-original=&https://pic3.zhimg.com/v2-a886ee0ce2a27b_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&2.2 使用 Matrix 来做变换&/b&&/h2&&h2&&b&2.2.1 使用 Matrix 来做常见变换&/b&&/h2&&p&Matrix 做常见变换的方式:&/p&&ol&&li&创建 Matrix 对象;&/li&&li&调用 Matrix 的 pre/postTranslate/Rotate/Scale/Skew() 方法来设置几何变换;&/li&&li&使用 Canvas.setMatrix(matrix) 或 Canvas.concat(matrix) 来把几何变换应用到 Canvas。&/li&&/ol&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Matrix matrix = new Matrix();
matrix.reset();
matrix.postTranslate();
matrix.postRotate();
canvas.save();
canvas.concat(matrix);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&p&效果就不放图了,和 Canvas 是一样的。&/p&&p&把 Matrix 应用到 Canvas 有两个方法: Canvas.setMatrix(matrix) 和 Canvas.concat(matrix)。&/p&&ol&&li&Canvas.setMatrix(matrix):用 Matrix 直接替换 Canvas 当前的变换矩阵,即抛弃 Canvas 当前的变换,改用 Matrix 的变换(注:根据我在一些评论以及微信公众号中收到的反馈,不同的手机系统中 setMatrix(matrix) 的行为可能不一致,所以还是尽量用 concat(matrix) 吧);&/li&&li&Canvas.concat(matrix):用 Canvas 当前的变换矩阵和 Matrix 相乘,即基于 Canvas 当前的变换,叠加上 Matrix 中的变换。&/li&&/ol&&h2&&b&2.2.2 使用 Matrix 来做自定义变换&/b&&/h2&&p&Matrix 的自定义变换使用的是 setPolyToPoly() 方法。&/p&&h2&&b&2.2.2.1 Matrix.setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount) 用点对点映射的方式设置变换&/b&&/h2&&p&poly 就是「多」的意思。setPolyToPoly() 的作用是通过多点的映射的方式来直接设置变换。「多点映射」的意思就是把指定的点移动到给出的位置,从而发生形变。例如:(0, 0) -& (100, 100) 表示把 (0, 0) 位置的像素移动到 (100, 100) 的位置,这个是单点的映射,单点映射可以实现平移。而多点的映射,就可以让绘制内容任意地扭曲。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Matrix matrix = new Matrix();
float pointsSrc = {left, top, right, top, left, bottom, right, bottom};
float pointsDst = {left - 10, top + 50, right + 120, top - 90, left + 20, bottom + 30, right + 20, bottom + 60};
matrix.reset();
matrix.setPolyToPoly(pointsSrc, 0, pointsDst, 0, 4);
canvas.save();
canvas.concat(matrix);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic4.zhimg.com/v2-ab0bbe3c4d4ae7_b.jpg& data-rawwidth=&942& data-rawheight=&552& class=&origin_image zh-lightbox-thumb& width=&942& data-original=&https://pic4.zhimg.com/v2-ab0bbe3c4d4ae7_r.jpg&&&/figure&&p&参数里,src 和 dst 是源点集合目标点集;srcIndex 和 dstIndex 是第一个点的偏移;pointCount 是采集的点的个数(个数不能大于 4,因为大于 4 个点就无法计算变换了)。&/p&&h2&&b&2.3 使用 Camera 来做三维变换&/b&&/h2&&p&Camera 的三维变换有三类:旋转、平移、移动相机。&/p&&h2&&b&2.3.1 Camera.rotate*() 三维旋转&/b&&/h2&&p&Camera.rotate*() 一共有四个方法: rotateX(deg) rotateY(deg) rotateZ(deg)rotate(x, y, z)。这四个方法的区别不用我说了吧?&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
camera.rotateX(30); // 旋转 Camera 的三维空间
camera.applyToCanvas(canvas); // 把旋转投影到 Canvas
canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
canvas.restore();
&/code&&/pre&&/div&&figure&&img src=&https://pic1.zhimg.com/v2-73c479412baeffd712b50b_b.jpg& data-rawwidth=&998& data-rawheight=&576& class=&origin_image zh-lightbox-thumb& width=&998& data-original=&https://pic1.zhimg.com/v2-73c479412baeffd712b50b_r.jpg&&&/figure&&p&另外,Camera 和 Canvas 一样也需要保存和恢复状态才能正常绘制,不然在界面刷新之后绘制就会出现问题。所以上面这张图完整的代码应该是这样的:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
camera.save(); // 保存 Camera 的状态
camera.rotateX(30); // 旋转 Camera 的三维空间
camera.applyToCanvas(canvas); // 把旋转投影到 Canvas
camera.restore(); // 恢复 Camera 的状态
canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
canvas.restore();
&/code&&/pre&&/div&&p&如果你需要图形左右对称,需要配合上 Canvas.translate(),在三维旋转之前把绘制内容的中心点移动到原点,即旋转的轴心,然后在三维旋转后再把投影移动回来:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.save();
camera.save(); // 保存 Camera 的状态
camera.rotateX(30); // 旋转 Camera 的三维空间
canvas.translate(centerX, centerY); // 旋转之后把投影移动回来
camera.applyToCanvas(canvas); // 把旋转投影到 Canvas
canvas.translate(-centerX, -centerY); // 旋转之前把绘制内容移动到轴心(原点)
camera.restore(); // 恢复 Camera 的状态
canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
canvas.restore();
&/code&&/pre&&/div&&blockquote&Canvas 的几何变换顺序是反的,所以要把移动到中心的代码写在下面,把从中心移动回来的代码写在上面。&/blockquote&&figure&&img src=&https://pic2.zhimg.com/v2-a0d6bfb625cbcd68f83c833e8c425b86_b.jpg& data-rawwidth=&842& data-rawheight=&462& class=&origin_image zh-lightbox-thumb& width=&842& data-original=&https://pic2.zhimg.com/v2-a0d6bfb625cbcd68f83c833e8c425b86_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&2.3.2 Camera.translate(float x, float y, float z) 移动&/b&&/h2&&p&它的使用方式和 Camera.rotate*() 相同,而且我在项目中没有用过它,所以就不贴代码和效果图了。&/p&&h2&&b&2.3.3 Camera.setLocation(x, y, z) 设置虚拟相机的位置&/b&&/h2&&p&注意!这个方法有点奇葩,它的参数的单位不是像素,而是 inch,英寸。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-b3ee9acefac4f3fb2d0bb44a_b.jpg& data-rawwidth=&308& data-rawheight=&251& class=&content_image& width=&308&&&/figure&&p&我 TM 的真没逗你,我也没有胡说八道,它的单位就。是。英。寸。&/p&&p&这种设计源自 Android 底层的图像引擎 &a href=&https://link.zhihu.com/?target=https%3A//skia.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Skia&/a& 。在 Skia 中,Camera 的位置单位是英寸,英寸和像素的换算单位在 Skia 中被写死为了 72 像素,而 Android 中把这个换算单位照搬了过来。是的,它。写。死。了。&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-2b3dfd91b4_b.jpg& data-rawwidth=&320& data-rawheight=&284& class=&content_image& width=&320&&&/figure&&p&吐槽到此为止,俗话说看透不说透,还是好朋友。&/p&&p&在 Camera 中,相机的默认位置是 (0, 0, -8)(英寸)。8 x 72 = 576,所以它的默认位置是 (0, 0, -576)(像素)。&/p&&p&如果绘制的内容过大,当它翻转起来的时候,就有可能出现图像投影过大的「糊脸」效果。而且由于换算单位被写死成了 72 像素,而不是和设备 dpi 相关的,所以在像素越大的手机上,这种「糊脸」效果会越明显。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-a5aae84fec4af50e2a4ad82_b.jpg& data-rawwidth=&1026& data-rawheight=&606& class=&origin_image zh-lightbox-thumb& width=&1026& data-original=&https://pic3.zhimg.com/v2-a5aae84fec4af50e2a4ad82_r.jpg&&&/figure&&p&&br&&/p&&p&而使用 setLocation() 方法来把相机往后移动,就可以修复这种问题。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&camera.setLocation(0, 0, newZ);
&/code&&/pre&&/div&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-3f1eeecdb53a48755f2c_b.jpg& data-rawwidth=&778& data-rawheight=&519& class=&origin_image zh-lightbox-thumb& width=&778& data-original=&https://pic1.zhimg.com/v2-3f1eeecdb53a48755f2c_r.jpg&&&/figure&&p&Camera.setLocation(x, y, z) 的 x 和 y 参数一般不会改变,直接填 0 就好。&/p&&p&好了,上面这些就是本期的内容:范围裁切和几何变换。&/p&&h2&&b&练习项目&/b&&/h2&&p&为了避免转头就忘,强烈建议你趁热打铁,做一下这个练习项目:&a href=&https://link.zhihu.com/?target=https%3A//github.com/hencoder/PracticeDraw4& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HenCoderPracticeDraw4&/a&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-5f61b15a317bee7a394619bda69754c9_b.jpg& data-rawwidth=&1013& data-rawheight=&562& class=&origin_image zh-lightbox-thumb& width=&1013& data-original=&https://pic1.zhimg.com/v2-5f61b15a317bee7a394619bda69754c9_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&下期预告&/b&&/h2&&p&到这期为止,所有绘制的「术」就讲完了,下期讲的是「道」:绘制顺序。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-dc4a3415285_b.jpg& data-rawwidth=&591& data-rawheight=&346& class=&origin_image zh-lightbox-thumb& width=&591& data-original=&https://pic2.zhimg.com/v2-dc4a3415285_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&特别感谢&/b&&/h2&&p&这次由于某些原因,没有依惯例邀请内测读者,但我需要特别感谢几个人:&/p&&ul&&li&特别感谢 &a href=&https://link.zhihu.com/?target=https%3A//github.com/GcsSloop& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GcsSloop&/a& 和 &a href=&https://link.zhihu.com/?target=https%3A//github.com/leethree& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeeThree&/a& 在我疲惫不堪的时候和我探讨问题、帮我做实验和寻找答案。&/li&&li&特别感谢 &a href=&https://link.zhihu.com/?target=https%3A//github.com/inferjay& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&脉脉不得语&/a& 在我忙得不可开交的时候帮我解决我的各种大小问题,以及帮我联系广告赞助商(别找了,这期没上广告,以后再上)。&/li&&/ul&&h2&&b&觉得赞?&/b&&/h2&&p&如果你看完觉得有收获,把文章转发到你的微博、微信群、朋友圈、公众号,让其他需要的人也看到吧。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-2cc73ac0dcafc2cb9d44cd5_b.jpg& data-rawwidth=&900& data-rawheight=&429& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic3.zhimg.com/v2-2cc73ac0dcafc2cb9d44cd5_r.jpg&&&/figure&&p&&/p&
这期是 HenCoder 自定义绘制的第 1-4 期:Canvas 对绘制的辅助——范围裁切和几何变换。之前的内容在这里:
&p&看了下youtube上的视频 &a href=&//link.zhihu.com/?target=https%3A//www.youtube.com/watch%3Fv%3DiFE2Utbv1Oo& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&youtube.com/watch?&/span&&span class=&invisible&&v=iFE2Utbv1Oo&/span&&span class=&ellipsis&&&/span&&/a&&/p&&p&貌似之前的Compact Copying Collector并不是concurrent的,然后在Android O里调整成为了Concurrent Copying Garbage Collector. 新的GC简单来说就是利用了read barrier来使得应用程序代码可以在GC过程中耗时最大的那些阶段依旧同GC一起运行。图是从Presentation里粘出来的,侵权删。&/p&&p&新的GC分为Pause, Copying, Reclaim三个阶段,以Region为单位进行GC。&/p&&p&Pause阶段:&/p&&figure&&img data-rawwidth=&1112& data-rawheight=&556& src=&https://pic4.zhimg.com/v2-c5f39f0ca3f2a0de87981b_b.png& class=&origin_image zh-lightbox-thumb& width=&1112& data-original=&https://pic4.zhimg.com/v2-c5f39f0ca3f2a0de87981b_r.png&&&/figure&&p&这个阶段耗时非常少,这里很重要的一块儿工作是确定需要进行GC的region。当前进程中所有正被使用的那些region中存在高度碎片的region会被选中,而这些被选中的region被称为source region。在GC完成后这些被选中的source region就可以被释放了。从图中可以看出本次GC选中了中间的两个碎片比率很大的region作为source region。在Pause阶段完成对所有线程stack的walk并得到最终的root set之后,就可以唤醒所有的线程并进入到GC的下一个Copying阶段。&/p&&p&Copying阶段:&/p&&figure&&img data-rawwidth=&1110& data-rawheight=&570& src=&https://pic2.zhimg.com/v2-e2c25dc3a8ad_b.png& class=&origin_image zh-lightbox-thumb& width=&1110& data-original=&https://pic2.zhimg.com/v2-e2c25dc3a8ad_r.png&&&/figure&&p&Copying阶段是整个GC中耗时最长的阶段。通过将source region中根据root set计算并标记为reachable的对象拷贝到destination region,并且确保在GC完成后没有任何指向source region中内存的引用,然后修改所有指向source region的活对象使他们指向新的destination region中的新地址。由于现在应用程序线程正在同GC线程一同运行,GC需要确保其它线程不会读到依旧指向source region的对象,而新的GC则使用了read barrier技术来达到这个目的。&/p&&figure&&img data-rawwidth=&1114& data-rawheight=&564& src=&https://pic3.zhimg.com/v2-742b6a5df838ff7603b97a_b.png& class=&origin_image zh-lightbox-thumb& width=&1114& data-original=&https://pic3.zhimg.com/v2-742b6a5df838ff7603b97a_r.png&&&/figure&&p&所谓read barrier是一小段代码,并且被运行期环境(runtime)安插在field read前来防止其它线程看到指向source region的引用。如果其它线程在Copying阶段需要访问曾经存在于source region中的对象,GC的read barrier逻辑会负责截获这个读取并且将数据拷贝到destination region然后返回这个被拷贝到destination region的新引用。当所有的source region的所有reachable对象都被转移到destination region之后就可以进入到GC的下一个Reclaim阶段了&/p&&figure&&img data-rawwidth=&1102& data-rawheight=&554& src=&https://pic4.zhimg.com/v2-1bf2f9700cc0cea9c201d646ca9a1ee3_b.png& class=&origin_image zh-lightbox-thumb& width=&1102& data-original=&https://pic4.zhimg.com/v2-1bf2f9700cc0cea9c201d646ca9a1ee3_r.png&&&/figure&&p&Reclaim阶段:在经过Copying阶段后,整个进程中就不再存在指向source regions的引用了,GC就可以将这些source region的内存释放供以后使用了。&/p&&p&新的GC算法在提高了GC效率的同时还得益于对后台任务甚至系统后台任务的支持,整个heap的平均尺寸得到了32%的下降。&/p&&figure&&img data-rawwidth=&992& data-rawheight=&552& src=&https://pic3.zhimg.com/v2-033fd4784aaefbc428b2f17e_b.png& class=&origin_image zh-lightbox-thumb& width=&992& data-original=&https://pic3.zhimg.com/v2-033fd4784aaefbc428b2f17e_r.png&&&/figure&&p&而平均GC Latency也得到了大大的降低,具体对比见图&/p&&figure&&img data-rawwidth=&1102& data-rawheight=&562& src=&https://pic3.zhimg.com/v2-e8d728ed6bc65ab4c2fdd0a_b.png& class=&origin_image zh-lightbox-thumb& width=&1102& data-original=&https://pic3.zhimg.com/v2-e8d728ed6bc65ab4c2fdd0a_r.png&&&/figure&&p&另外由于heap总是经过compact的,从而可以实现Thread Local Bump Pointer的简单内存分配器,因为现在分配内存不再需要复杂的free list管理只需要一个简单的pointer bump,内存分配的速度也得到了显著的提升。&/p&&figure&&img data-rawwidth=&1116& data-rawheight=&544& src=&https://pic3.zhimg.com/v2-dc4789cbc05c6cfbcba6ef6_b.png& class=&origin_image zh-lightbox-thumb& width=&1116& data-original=&https://pic3.zhimg.com/v2-dc4789cbc05c6cfbcba6ef6_r.png&&&/figure&
看了下youtube上的视频 貌似之前的Compact Copying Collector并不是concurrent的,然后在Android O里调整成为了Concurrent Copying Garbage Collector. 新的GC简单来说就是利用了read barrier来使得应用程序代码可以在GC过程中耗时最大…
&figure&&img src=&https://pic7.zhimg.com/v2-bc9ebc46afb_b.jpg& data-rawwidth=&600& data-rawheight=&314& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&https://pic7.zhimg.com/v2-bc9ebc46afb_r.jpg&&&/figure&&p&当一个 App 发布之后,突然发现了一个严重 bug 需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包 App、测试、向各个应用市场和渠道换包、提示用户升级、用户下载、覆盖安装。有时候仅仅是为了修改了一行代码,也要付出巨大的成本进行换包和重新发布。这时候就提出一个问题:有没有办法以补丁的方式动态修复紧急Bug,不再需要重新发布App,不再需要用户重新下载,覆盖安装?答案当然是有的,那就是最近涌现出来得热补丁方案。&br&&/p&&p&截止目前国内包含支付宝、淘宝、微信、QQ空间、饿了么、美丽说蘑菇街、美团大众点评等团队都推出了自己的热修复方案。(以下图片来自美丽说蘑菇街热修复文章分析)&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-3c1cbe45adf10055c11ec_b.png& data-rawwidth=&1260& data-rawheight=&816& class=&origin_image zh-lightbox-thumb& width=&1260& data-original=&https://pic1.zhimg.com/v2-3c1cbe45adf10055c11ec_r.jpg&&&/figure&&p&1、&a href=&http://link.zhihu.com/?target=http%3A//blog.zhaiyifan.cn//HotPatchCompare/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& Dexposed、AndFix、ClassLoader等各大热补丁方案分析和比较&/a&&/p&&p&主要分析了 Dexposed、AndFix、ClassLoader 这三种方案的原理原理和各自的优缺点,感觉现在文章可以加入 Instant Run 和微信的 Tinker 热补丁方案了&/p&&p&2、&a href=&http://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzI1MTA1MzM2Nw%3D%3D%26mid%3Didx%3D1%26sn%3Db4fddeef12ad0d17f39d4a& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android App 热补丁动态修复技术介绍及 QQ 空间热补丁动态修复技术方案原理&/a&&/p&&p&Android QQ空间团队提出了独特的解决方法,该方案基于的是android dex分包方案的。具体大家直接点击原文查看&/p&&p&3、&a href=&http://link.zhihu.com/?target=https%3A//github.com/WeMobileDev/article/blob/master/%25E5%25BE%25AE%25E4%25BF%25A1Android%25E7%2583%25AD%25E8%25A1%25A5%25E4%25B8%%25AE%259E%25E8%25B7%25B5%25E6%25BC%%25BF%259B%25E4%25B9%258B%25E8%25B7%25AF.md%23rd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&微信 Android 热补丁实践演进之路&/a&&/p&&p&文章介绍了热补丁主要是让应用能够在无需重新安装的情况实现更新,帮助应用快速建立动态修复能力,同时对比了 Dexposed、AndFix、QQ 空间的 ClassLoader 等等的业务局限然后根据微信自身的需求推出了微信自己的热补丁方案 Tinker。&/p&&p&4、&a href=&http://link.zhihu.com/?target=http%3A//blog.csdn.net/qxs/article/category/5949113& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Alibaba 热修复方案系列文章(包含 AndFix、Dexposed 框架)&/a&&/p&&p&Alibaba 出品的热修复方案,主要涉及到AndFix、Dexposed框架的使用和原理分析。&/p&&p&5、&a href=&http://link.zhihu.com/?target=https%3A//medium.com/google-developers/instant-run-how-does-it-work-294a.c088qhdxu& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Instant Run英文原文(需要科学上网)&/a&&/p&&p&6、&a href=&http://link.zhihu.com/?target=http%3A//www.jianshu.com/p/2e23ba9ff14b& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Instant Run工作原理及用法&/a&&/p&&p&第5、第6篇,简单明了的带你看懂Instant Run的运作方式。&/p&&p&7、&a href=&http://link.zhihu.com/?target=http%3A//www.jianshu.com/p/72c17fb76f21& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&基于Nuwa实现 Android 自动化 HotFix&/a&&/p&&p&8、&a href=&http://link.zhihu.com/?target=http%3A//blog.csdn.net/sbsujjbcy/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 热修复 Nuwa 的原理及 Gradle 插件源码解析&/a&&/p&&p&第7、8篇文章,基于开源框架 Nuwa 来实现的热修复方案。&/p&&p&9、&a href=&http://link.zhihu.com/?target=https%3A//github.com/meili/Aceso& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Aceso:美丽说蘑菇街开源的 Android 热修复方案&/a& ( GitHub 地址 )&/p&10、&a href=&http://link.zhihu.com/?target=http%3A//mp.weixin.qq.com/s/GuzbU1M1LY1VKmN7PyVbHQ& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&蘑菇街 Android 热修复探索之路&/a& ( 技术解读 )&p&基于 Instant Run Hot Swap 的 Android 热修复方案,使用它你能在不用重新发布版本的情况下对线上 app 的 bug 进行修复。&br&&/p&&p&11、&a href=&http://link.zhihu.com/?target=https%3A//github.com/Meituan-Dianping/Robust& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Robust:美团第二代热修复框架&/a&(GitHub 地址)&/p&&p&12、&a href=&http://link.zhihu.com/?target=http%3A//tech.meituan.com/android_robust.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&美团 Android 热更新方案 Robust &/a&( 技术解读 )&/p&&br&&p&新一代热更新系统Robust,对Android版本无差别兼容。无需发版就可以做到随时修改线上bug,快速对重大线上问题作出反应,补丁修补成功率高达99.9%。&br&&/p&&p&13、&a href=&http://link.zhihu.com/?target=https%3A//github.com/eleme/Amigo& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Amigo:饿了么热修复开源&/a&(GitHub 地址)&/p&&p&14、&a href=&http://link.zhihu.com/?target=https%3A//www.diycode.cc/topics/375& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&饿了么热修复开源解决方案 Amigo 0.4.4 源码解读&/a&&/p&&p&Amigo是业界比较成熟的Hotfix解决方案,同时它适用的业务场景也并不会局限于此。如果你的团队是采用并行开发的话,发版周期会将是一个非常头疼问题,有了Amigo,这些都将不再是困扰业务的快速发展。&/p&&br&&p&Android 热修复技术经过这几年发展已经非常成熟了,以上那么多轮子总有一个适合你。&/p&
当一个 App 发布之后,突然发现了一个严重 bug 需要进行紧急修复,这时候公司各方就会忙得焦头烂额:重新打包 App、测试、向各个应用市场和渠道换包、提示用户升级、用户下载、覆盖安装。有时候仅仅是为了修改了一行代码,也要付出巨大的成本进行换包和重新…
&p&现在的程序员比较偏爱mac,除了苹果自身的高颜质和高质量外,很大程度上还是因为 mac 的系统要比 windows 好用。当然前提是能找到和自己工作相对应的软件,像 plsql、powerdesigner 这样的软件目前还是没有较好的替代方案。我日常的开发工作主要是 java 和 web 两个方向。java 用于开发协议和微服务,涉及到 tomcat、nginx、各种依赖服务,如:redis、memcached、mongodb、rmq、zookeeper等。web 方向涉及到 webpack、vue、fis3、extjs、d3js 等技术。结合我自己的习惯,给大家介绍一些使用经验,主要目的:保持电脑环境的纯净和提升工作效率。&/p&&br&&figure&&img src=&https://pic3.zhimg.com/v2-5b5b17a9df330c2aeece_b.png& data-rawwidth=&1172& data-rawheight=&860& class=&origin_image zh-lightbox-thumb& width=&1172& data-original=&https://pic3.zhimg.com/v2-5b5b17a9df330c2aeece_r.png&&&/figure&&p&我电脑目前的磁盘使用情况&/p&&blockquote&如果你也希望自己的电脑一直都操持纯净,不想哪天被提示没有存储空间或者莫名其妙的发现没装几个软件,磁盘的占用率却已经很高,即使卸载软件也起不了多少用,可以花几分钟时间了解下以下的内容,应该能有所收获。
PS:我的电脑硬盘分 os 和 data 两个区,下文中提到的 homebrew,docker,maven,node 都属于资源管理类型的软件,通常会占用较大的存储空间,比如docker的镜像存储目录,maven的本地库。因此建议全部采用软链的方式,将这些资源统一存储到data分区中,以控制os分区的占用空间。&/blockquote&&p&&b&1、使用time machine 苹果自带的备份工具备份电脑&/b&&/p&&br&&figure&&img src=&https://pic1.zhimg.com/v2-cb009dc19fa4_b.jpg& data-rawwidth=&1336& data-rawheight=&856& class=&origin_image zh-lightbox-thumb& width=&1336& data-original=&https://pic1.zhimg.com/v2-cb009dc19fa4_r.jpg&&&/figure&&p&time machine 完成首次备份
&/p&&blockquote&time machine是苹果自带的备份工具,可以随时备份和还原到指定的时刻,像我这样爱折腾又有洁癖(仅针对电子产品^-^)的人,对软件安装后的垃圾问题向来零容忍,所以通常我会在装好系统的时候立刻备份一次,然后开始安装主要的工作环境,完成后再备份一次。如果中途出了任何问题立刻恢复重来。这两次备份做好后以后就关闭time machine 不再备份了,我可不想因为备份磁盘不足将这两个重要的成果给自动删除了。今后工作过程中产生的资料、代码将统一交给git存储,这是一个良好的工作习惯。&/blockquote&&p&&b&2、使用homebrew 管理你的软件&/b&&/p&&p&/usr/bin/ruby -e &$(curl -fsSL &a href=&//link.zhihu.com/?target=https%3A//raw.githubusercontent.com/Homebrew/install/master/install& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&raw.githubusercontent.com&/span&&span class=&invisible&&/Homebrew/install/master/install&/span&&span class=&ellipsis&&&/span&&/a&)&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-98f150e6a3b91a8a918f70f2dc96f615_b.jpg& data-rawwidth=&1850& data-rawheight=&682& class=&origin_image zh-lightbox-thumb& width=&1850& data-original=&https://pic2.zhimg.com/v2-98f150e6a3b91a8a918f70f2dc96f615_r.jpg&&&/figure&&p&homebrew 安装提示
&/p&&blockquote&homebrew 的安装过程非常简单,网上也有很多的教程可供参考,图中的提示可以复制链接到网页,在 github 上生成一个 token 并按上面的提示写入到环境变量中就可以开始使用了。一句话总结:能用 homebrew 安装的软件一概用它安装。
brew search [TEXT|/REGEX/] 搜索线上的软件
brew install FORMULA...
brew update 更新 homebrew 自己
brew upgrade [FORMULA...] 更新软件
brew uninstall FORMULA... 删除软件
brew list [FORMULA...] 查看本机安装的软件&/blockquote&&p&&b&3、使用 iterm2 替换苹果默认的终端 &/b&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-1aeb57fbdac53f85f469e78d_b.jpg& data-rawwidth=&2378& data-rawheight=&1066& class=&origin_image zh-lightbox-thumb& width=&2378& data-original=&https://pic2.zhimg.com/v2-1aeb57fbdac53f85f469e78d_r.jpg&&&/figure&&p&iterm2 配置好后的效果
&/p&&blockquote&iterm2 是很多人都推荐的工具,可以水平或者纵向分割窗口,配合 zsh、 oh-my-zsh、 solarized 配色、Powerline 字体、coreutils 就可以达到上图中的炫酷效果。另外任何你之前使用过的命令还可以通过上下键翻出来,你也可以先输入几个开始的字母后再按上下键查找,大大的提高了工作效率。它的配置过程稍复杂一些,也可以参考我git上的文章 &a href=&//link.zhihu.com/?target=https%3A//github.com/lenxeon/notes/tree/master/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&github.com/lenxeon/note&/span&&span class=&invisible&&s/tree/master/&/span&&span class=&ellipsis&&&/span&&/a& 配置。另外做为一个服务器开发者,一定要多掌握一些常用 shell 命令,像 grep awk tail seed curl find 这些命令能够帮助我们快速地分析日志,做起事来事半功倍。&/blockquote&&p&&b&4、使用docker 搭建各种服务环境zk、数据库、rmq等&/b& &/p&&figure&&img src=&https://pic1.zhimg.com/v2-b94c534b5efe6a4fcc1cec_b.jpg& data-rawwidth=&1986& data-rawheight=&1102& class=&origin_image zh-lightbox-thumb& width=&1986& data-original=&https://pic1.zhimg.com/v2-b94c534b5efe6a4fcc1cec_r.jpg&&&/figure&&p&注册个国内的镜像加速&/p&&figure&&img src=&https://pic4.zhimg.com/v2-d374775bdb98beb69e21e9b7_b.jpg& data-rawwidth=&760& data-rawheight=&1010& class=&origin_image zh-lightbox-thumb& width=&760& data-original=&https://pic4.zhimg.com/v2-d374775bdb98beb69e21e9b7_r.jpg&&&/figure&&p&设置使用国内镜像加速 &/p&&figure&&img src=&https://pic4.zhimg.com/v2-2c9c6d3fc93_b.jpg& data-rawwidth=&2160& data-rawheight=&1360& class=&origin_image zh-lightbox-thumb& width=&2160& data-original=&https://pic4.zhimg.com/v2-2c9c6d3fc93_r.jpg&&&/figure&&p&kitematic 管理器
&/p&&figure&&img src=&https://pic2.zhimg.com/v2-d845ce90be8eca9f414e19_b.jpg& data-rawwidth=&1880& data-rawheight=&1282& class=&origin_image zh-lightbox-thumb& width=&1880& data-original=&https://pic2.zhimg.com/v2-d845ce90be8eca9f414e19_r.jpg&&&/figure&&p&docker-compose服务编排 &/p&&blockquote&docker是近年来非常热门的技术,容器化,弹性云计算这些耳熟能详的词语都跟他有关。使用 docker-compose 来编排应用,可以真正做到一键安装,大大的降低了目标客户安装软件的难度。目前对我来说最大的好处是实现了母机环境的纯净管理。有了 docker 所有的配置尝试、变量修改、软件安装全部都在容器内进行,这些修改都将随着容器的删除而彻底删除,再也不用担心母机的软件越装越多,硬盘占用越来越大,软件删除后的顽固垃圾无法真正彻底的清理干净,环境变量杂乱、冲突等问题了。 它主要的功能有:
将应用程序便携式部署成单一对象,而不是进程沙箱;
以应用程序为中心,而不是以机器/服务器为中心;
支持容器自动化构建;
内置版本控制功能;
可重复使用的组件;
共享容器的公共注册中心;
借助已发布的API,建立日益庞大的工具生态系统。我们理想的应用方式是:在docker的基础上结合 gitlab,jenkins 和我们鱼骨软件的 im 服务构建一套持续集成的开发管理模式。当成员提交代码到 git 后,git 会通知到 jenkins 触发相应的自动化测试,测试完成后会将测试报告发布给鱼骨的订阅群组,如果遇到测试不通过的情况则由相关的开发者查明原因、修正并重新提交代码。这样可以极大程度的保证代码的质量,减少测试人员的重复劳动,提升工作效率
PS 因为docker默认的镜像库在国外,导致拉取镜像的时候速度超慢,因此我们需要注册一个国内的镜像库。&/blockquote&&p&&b&5、使用Dash管理你的文档&/b&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-5f27ab944fa96d02e198eac4a38eff73_b.jpg& data-rawwidth=&1416& data-rawheight=&1156& class=&origin_image zh-lightbox-thumb& width=&1416& data-original=&https://pic4.zhimg.com/v2-5f27ab944fa96d02e198eac4a38eff73_r.jpg&&&/figure&&p&dash 提供了大量的文档供下载&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e8fc6ebe3d1_b.jpg& data-rawwidth=&2056& data-rawheight=&1194& class=&origin_image zh-lightbox-thumb& width=&2056& data-original=&https://pic2.zhimg.com/v2-e8fc6ebe3d1_r.jpg&&&/figure&&p&使用dash查找vue的api&/p&&blockquote&dash 是mac上最好最全的文档管理工具,本身提供了大量的文档供下载,几乎各类语言的各个版本都可以在这里找到相应的文档,而且使用起来也非常简单方便。&/blockquote&&p&&b&6、使用Xmind管理你的思路&/b&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-ef51733d5de_b.jpg& data-rawwidth=&1636& data-rawheight=&1264& class=&origin_image zh-lightbox-thumb& width=&1636& data-original=&https://pic3.zhimg.com/v2-ef51733d5de_r.jpg&&&/figure&&p&用户服务相关的部分功能 &/p&&blockquote&我们在做服务开发的时候,经常需要思考这么几个问题:如何拆分服务,目前已经提供了哪些服务,还有哪些可以完善的服务。脑图工具可以很好的帮助我解决这些问题,脑图节点就代表着如何拆分,已经提供服务的用已完成标记,认为有问题可以改善的服务可以用感叹号标记,还未做的服务用未启动标记。脑图工具有很多可选,像业内知名的有 xmind, mindmanager 。随着云概念的火热,现在也有很多的在线脑图工具可选择,包括我们的鱼骨软件也都有提供在线脑图这样的功能。&/blockquote&&p&&b&7、使用 IntelliJ IDEA 开发 java&/b&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-14c0cea7f0_b.jpg& data-rawwidth=&2046& data-rawheight=&1422& class=&origin_image zh-lightbox-thumb& width=&2046& data-original=&https://pic1.zhimg.com/v2-14c0cea7f0_r.jpg&&&/figure&&p&idea 的开发界面 &/p&&figure&&img src=&https://pic3.zhimg.com/v2-da2ffc816b24f62c8fcd9ee_b.png& data-rawwidth=&2200& data-rawheight=&1280& class=&origin_image zh-lightbox-thumb& width=&2200& data-original=&https://pic3.zhimg.com/v2-da2ffc816b24f62c8fcd9ee_r.png&&&/figure&&p&idea 配色后的的开发界面 &/p&&blockquote&提到idea不得不说说jetbrains这家公司,真心的很佩服他们。idea、 webStorm、 phpStorm 每一款编辑器都倍受好评。我使用idea大概 5 年了,除了头两年还有用 eclipse 外一直在用它,究竟好在哪里真有点说不上来,但用过以后你心里就是会觉得它好,有点像苹果的产品,爱在不言中。
PS: &a href=&//link.zhihu.com/?target=http%3A//color-themes.com/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&color-themes.com/&/span&&span class=&invisible&&&/span&&/a& 这里有很多的配色方案,下载后导入即可&/blockquote&&p&&b&8、sublime text / atom web开发的神器&/b&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-9d890cba563f5b4376c94_b.jpg& data-rawwidth=&1910& data-rawheight=&1324& class=&origin_image zh-lightbox-thumb& width=&1910& data-original=&https://pic1.zhimg.com/v2-9d890cba563f5b4376c94_r.jpg&&&/figure&&p&sublime text 的开发界面 &/p&&figure&&img src=&https://pic3.zhimg.com/v2-4b9c026ab9d54e9570ffef85c4122bfe_b.jpg& data-rawwidth=&1884& data-rawheight=&1298& class=&origin_image zh-lightbox-thumb& width=&1884& data-original=&https://pic3.zhimg.com/v2-4b9c026ab9d54e9570ffef85c4122bfe_r.jpg&&&/figure&&p&atom 的开发界面
&/p&&blockquote&两个非常有名的文本编辑器,从性能上讲 sublime 更强,加载一个较大的文件就看出来。atom毕竟是用JS编写的产品,所以这点也说的过去了。之所以两个都装是因为我经常切换项目做一些参考,而且两个产品还是有一些不同的特点,小文件编写我更常用 atom。另外单就 web 开发而言还是尽量抛弃那些比较笨重的开发工具吧,比如当年的dreamware。用这两个编辑器能帮助你快速掌握前端那些标签,样式,函数,一点也不比用 dreamware 慢,如果说还有比它更适合前端开发的编辑器那估计就只能是 webstorm 了。&/blockquote&&p&&b&9、使用jenv/nvm 管理java和node的多版本环境 &/b&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-70cbda6dc706dd23542c8_b.jpg& data-rawwidth=&1540& data-rawheight=&1176& class=&origin_image zh-lightbox-thumb& width=&1540& data-original=&https://pic1.zhimg.com/v2-70cbda6dc706dd23542c8_r.jpg&&&/figure&&p&jenv 切换不同版本的jdk演示 &/p&&blockquote&在开发的过程中,偶尔会遇到需要使用不同版本的 jdk,nodejs 的场景。这两个命令可以方便的帮助我们实现不同版本的切换功能,想用哪个版本就用哪个版本,再也不用手忙脚乱的去修改环境配置了。&/blockquote&&p&&b&10、使用 tower 管理你的 git 项目&/b&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dd89f9eef_b.jpg& data-rawwidth=&1854& data-rawheight=&1194& class=&origin_image zh-lightbox-thumb& width=&1854& data-original=&https://pic4.zhimg.com/v2-dd89f9eef_r.jpg&&&/figure&&p&新版的tower支持很多种账户类型 &/p&&figure&&img src=&https://pic3.zhimg.com/v2-1b483f1ca_b.jpg& data-rawwidth=&1848& data-rawheight=&1366& class=&origin_image zh-lightbox-thumb& width=&1848& data-original=&https://pic3.zhimg.com/v2-1b483f1ca_r.jpg&&&/figure&&p&项目代码管理界面&/p&&blockquote&tower 提供了git 的 GUI 管理界面,极大的降低了 git 的入门难度。是 git 入门者、命令恐惧者的福音。&/blockquote&&p&&b&11、使用 omnigraffle 画图&/b&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-16a5e6e5edf5dba00f57689cebe0a7ef_b.png& data-rawwidth=&1242& data-rawheight=&804& class=&origin_image zh-lightbox-thumb& width=&1242& data-original=&https://pic4.zhimg.com/v2-16a5e6e5edf5dba00f57689cebe0a7ef_r.png&&&/figure&&p&omnigraffle 画的应用场景示意图&/p&&figure&&img src=&https://pic4.zhimg.com/v2-8da136d67e7a30b121057b_b.png& data-rawwidth=&1358& data-rawheight=&934& class=&origin_image zh-lightbox-thumb& width=&1358& data-original=&https://pic4.zhimg.com/v2-8da136d67e7a30b121057b_r.png&&&/figure&&p&omnigraffle 画的系统部署示意图 &/p&&blockquote&又是一家需要膜拜的软件公司,每一款产品都很出名 omnigraffle 、omniplan、 OmniOutliner、omnifocus。我喜欢用它的 omnigraffle 画图工具。软件本身并不大,提供一些基础的矢量素材供使用,同时也可以自己从网上下载素材导入使用。&/blockquote&&p&&b&12、使用 鱼骨软件 来管理团队日常工作&/b&&/p&&figure&&img src=&https://pic3.zhimg.com/v2-3ac16c5aa40f4cc061a2_b.jpg& data-rawwidth=&2634& data-rawheight=&1496& class=&origin_image zh-lightbox-thumb& width=&2634& data-original=&https://pic3.zhimg.com/v2-3ac16c5aa40f4cc061a2_r.jpg&&&/figure&&p&任务的协作界面 &/p&&figure&&img src=&https://pic3.zhimg.com/v2-4cd87ad888f97f1a1a5de249ff9d87ba_b.jpg& data-rawwidth=&1684& data-rawheight=&1164& class=&origin_image zh-lightbox-thumb& width=&1684& data-original=&https://pic3.zhimg.com/v2-4cd87ad888f97f1a1a5de249ff9d87ba_r.jpg&&&/figure&&p&早上的工作提醒,重要的协作通知&/p&&figure&&img src=&https://pic2.zhimg.com/v2-b16bbbe5a37d459b50c1ec822dfe77ad_b.jpg& data-rawwidth=&1684& data-rawheight=&1164& class=&origin_image zh-lightbox-thumb& width=&1684& data-original=&https://pic2.zhimg.com/v2-b16bbbe5a37d459b50c1ec822dfe77ad_r.jpg&&&/figure&&p&部门群中的日常沟通&/p&&blockquote&这是我们自己开发的办公协作软件: &a href=&//link.zhihu.com/?target=http%3A//www.yugusoft.com/p/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&yugusoft.com/p/&/span&&span class=&invisible&&&/span&&/a& ,主要的功能包括:项目管理,任务,文档,同事圈,IM。目前我们内部的管理工作已经全在这个软件中进行。每周一在公司的周会中定义下本周的开发计划,再回到部门中召开一个十分钟左右的站立会议,给部门成员传达本周的工作重点,会后拆解成相应的任务落实到具体的负责人进行开发,任务需求相关的原型图和设计稿由产品和设计的同事以附件的方式提交到任务中。中途有疑问的地方可以在评论或者Im中进行沟通,如果沟通不顺畅则会组织一个小范围的面对面讨论,达成一致意见后再次将新的共识更新到任务评论或附件中。&/blockquote&&p&&b&13、结语&/b&&/p&&blockquote&除了上面这些软件外还有一些其它的软件,像:chrome,navicat,gitbook 等等就不再一一截图展示了。以上这些已经满足了我日常的使用需求,而且涉及到软件安装,环境搭建的问题已都有了较好的解决办法,主要还是归功于 homebrew 和 docker 两款软件。如果您喜欢这篇文章请帮我点个赞~~。&/blockquote&&p&============================&/p&&p&看到大家争论分区问题,我觉得要坚持分区,这是一种对待系统和数据的态度。实际上所谓的空间利用率这点我觉得是占不住脚的,比如最小128G的硬盘并不会因为分两个区就少放东西了,实际上本身我们也放不满整个硬盘,比如60G的系统,60G的数据,我们会有60G的数据需要放么,感觉是不太可能的,除非是资料收集者,比如电影、视频之类的。所以我的数据盘里一般只有代码,文档,图片,而它们一般也就在10-30G左右。分了区会在find的设备里有一个入口,结构也更清晰。而且这个和windws其实是一样的,为啥windows里面我们会分成:系统,游戏,娱乐等等,到了mac上分区就不行了呢?&/p&&figure&&img src=&https://pic1.zhimg.com/v2-4fdc5f018e2a17ada7b13cf0_b.png& data-rawwidth=&1542& data-rawheight=&868& class=&origin_image zh-lightbox-thumb& width=&1542& data-original=&https://pic1.zhimg.com/v2-4fdc5f018e2a17ada7b13cf0_r.png&&&/figure&&br&&p&============================&/p&&p&最近开了个公众号:“程序员自我修炼之道”,欢迎大家关注~~&/p&&br&&br&&p&&a href=&//link.zhihu.com/?target=http%3A//weixin.qq.com/r/fTh4YOfE-LqDraMD921v& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&weixin.qq.com/r/fTh4YOf&/span&&span class=&invisible&&E-LqDraMD921v&/span&&span class=&ellipsis&&&/span&&/a& (二维码自动识别)&/p&
现在的程序员比较偏爱mac,除了苹果自身的高颜质和高质量外,很大程度上还是因为 mac 的系统要比 windows 好用。当然前提是能找到和自己工作相对应的软件,像 plsql、powerdesigner 这样的软件目前还是没有较好的替代方案。我日常的开发工作主要是 java 和 …
&h1&Android-Tips&/h1&&p&This is an awesome list of tips for android.&/p&&p&If you are a beginner, this list will be the first choice for you when you have a difficult time.&/p&&p&Welcome Star and Fork, your support is my greatest affirmation.&/p&&p&学习 Android 至今,大大小小的坑没少踩过,庆幸的是,在强大的搜索引擎与无私奉献的人们的帮助下,那些坑都顺利地被填平了。&/p&&p&为了日后在遇到同样的问题时,能免于再次搜索带来的麻烦,我养成了收藏书签的习惯,随着书签(Tips)的日积月累,我想,是时候该有这个项目了。&/p&&p&如果你是个 Android 新人,又不善于搜索或不知道从何开始,那么我相信这份列表,将会成为你的首选。&/p&&p&当然,这份列表并不完美,如果不幸,这里没有你所踩到的坑,或者对于某个问题你有更好的 Tips,欢迎与大家分享,让我们一起来维护这个项目!&/p&&p&你可以通过 &a href=&https://link.zhihu.com/?target=https%3A//github.com/tangqi92/Android-Tips/pulls& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Pull request&/a& 的形式进行提交,当然也欢迎 Star 与 Fork :)&/p&&blockquote&&p&由于各种问题,给出的链接可能会无法正常访问。遇到这种情况欢迎大家提交 &a href=&https://link.zhihu.com/?target=https%3A//github.com/tangqi92/Android-Tips/issues& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Issue&/a&,Contributers 也可以使用 &a href=&https://link.zhihu.com/?target=https%3A//github.com/tangqi92/Android-Tips/tree/master/Utils& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Utils&/a& 里面的 &a href=&https://link.zhihu.com/?target=https%3A//github.com/tangqi92/Android-Tips/blob/master/Utils/UrlCheckerREADME.md& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&URLChecker&/a& 来检测列表里链接的有效性,你可以选择更改为新的有效连接,或者把需要梯子的文章以 Markdown 的形式保存在 Utils/Content 目录下,并注明原文章链接和作者。&/p&&/blockquote&&h3&A&/h3&&h3&ADB&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=https%3A//www.youtube.com/watch%3Fv%3D5U_BfrXV90I& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Installing ADB on Windows 7&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//android.jobbole.com/61592/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android ADB常用命令&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.cnblogs.com/meil/archive//2516055.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android开发调试工具ADB的使用&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.stormzhang.com/android//adb-over-wifi/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android通过Wifi来调试你的应用&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.oschina.net/question/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Adb connection Error:远程主机强迫关闭了一个现有的连接&/a&&/li&&/ol&&h3&Adapter&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.stormzhang.com/androidtips//android-common-simplebaseadapter/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android简便通用的SimpleBaseAdapter&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//stackvoid.com/using-adapter-in-efficiency-way/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android数据适配器(Adapter)优化:使用高效的ViewHolder&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/lmj/article/details//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 快速开发系列 打造万能的ListView GridView 适配器&/a&&/li&&/ol&&h3&AIDL&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/saintswordsman/article/details/5130947& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android进程间通信:使用AIDL&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/stonecao/article/details/6425019& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android AIDL使用详解&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/singwhatiwanna/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android跨进程通信(IPC): 使用AIDL&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/notice520/article/details/8135600& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android中的跨进程通信的实现(一)——远程调用过程和aidl&/a&&/li&&/ol&&h3&Android-Async-Http&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=https%3A//github.com/loopj/android-async-http& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Asynchronous Http Client for Android&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.cnblogs.com/angeldevil/p/3729808.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&快速Android开发系列网络篇之Android-Async-Http&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//yanbober.github.io//csdn-opensource-analysis-5/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android-async-http框架库使用基础&/a&&/li&&/ol&&h3&Android Studio&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//ask.android-studio.org/%3F/article/21& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio导入项目&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.gaoqixhb.com/p/54b9c293bf1ac& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio 简单设置&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//drakeet.me/android-studio& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio 简介及导入 jar 包和第三方开源库方法&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/growth58/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio使用技巧系列教程(一)&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/wei/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio中如何使用Git和Github来管理项目&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/column/details/zsl-androidstudio.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio 权威教程&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//zlv.me/posts//14_android-studio-tips/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&倍数提高工作效率的Android Studio奇技&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/altair86/article/details/8972178& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio 快捷键(Windows)&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.stormzhang.com/devtools//android-studio-all/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android Studio详细教程汇总&/a&&/li&&li&&a href=&http://www.zhihu.com/question/& class=&internal&&Android Studio有什么奇技淫巧&/a&&/li&&/ol&&h3&AQuery&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//programmerguru.com/android-tutorial/aquery-image-loading/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AQuery Image Loading&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.cnblogs.com/lee0oo0/archive//2738299.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android之使用Android-query框架进行开发(一)&/a&&/li&&/ol&&h3&AsyncTask&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/guolin_blog/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android AsyncTask完全解析,带你从源码的角度彻底理解&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/cjjky/article/details/6684959& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android中AsyncTask的简单用法&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//code.oneapm.com/android//android1/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android开发者:你真的会用AsyncTask吗?&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//www.cnblogs.com/anee/archive//2699829.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&深入解析AsyncTask,多例子版&/a&&/li&&/ol&&h3&Annotations&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//zhenhappy.github.io//Android-Annotations-1-Introduce.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&AndroidAnnotations框架入门教程一之介绍&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//stackoverflow.com/questions/4112599/how-to-stop-an-animation-cancel-does-not-work& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How to stop an animation (cancel() does not work)&/a&&/li&&/ol&&h2&B&/h2&&h3&Bitmap&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//beartung.github.io/rockwithandroid/image.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&图片处理&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/appandroid/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android中自定义布局中加载图片BitmapFactory.options详解&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/sjf0115/article/details/7267532& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android学习笔记进阶16之BitmapShader&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//chjmars.iteye.com/blog/1157137& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 优化Bitmap避免OutOfMemoryError&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/xiaanming/article/details/9825113& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//bugly.qq.com/bbs/forum.php%3Fmod%3Dviewthread%26tid%3D498%26fromuid%3D6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存?&/a&&/li&&/ol&&h3&Broadcast&/h3&&ol&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/jueblog/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【Android】BroadCast广播机制应用与实例&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//hualang.iteye.com/blog/1003374& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&玩转Android---组件篇---Broadcast Receiver(广播接收器)&/a&&/li&&li&&a href=&https://link.zhihu.com/?target=http%3A//blog.csdn.net/etzmico/article/details/7317528& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&【Android】动态注册广播接收器&/a&&/li&&/ol&&br&学习目录小编已经为大家按照字母顺序A-W罗列,以上是A-B,&a href=&https://link.zhihu.com/?target=https%3A//yq.aliyun.com/articles/32546& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&若喜欢可以点此此处移步查看C-W详情&/a&
Android-TipsThis is an awesome list of tips for android.If you are a beginner, this list will be the first choice for you when you have a difficult time.Welcome Star and Fork, your support is my greatest affirmation.学习 Android 至今,大…
&figure&&img src=&https://pic4.zhimg.com/2733913aaec8617aaba

我要回帖

更多关于 http www.ynzbw.com 的文章

 

随机推荐