面试时应该注意的问题,问哪些问题能试出一个 Android 应用开发者真正的水平

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》研发主编,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
个人大数据技术博客:&b&在收藏的同时,麻烦顺手点个赞,谢谢啦!!&/b&&br&&br&最近看到很多人都在找工作, 而且很多人都感觉今年找工作比去年难很多, 竞争力也增加不少, 因此激发我整理这份资料, 希望能帮到正在找或者准备找工作的童鞋们.&br&&br&首先我们能否获得一个面试机会, 那肯定是从简历开始, 简历需要做好功夫,
一份好的简历才足够吸引企业得到面试机会, 接着就是面试了, 面试前必须要先做好准备, 多看一下前辈们总结面试题, 有哪一方面不足的地方赶紧补充一下, 还有要了解一下你即将面试那家公司.&br&&br&&b&教你写简历&/b&&br&&ul&&li&&a href=&///?target=http%3A//mp./s%3F__biz%3DMzA4NTQwNDcyMA%3D%3D%26mid%3Didx%3D1%26sn%3Db50cc01a83f%26scene%3D21%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&你真的会写简历么?&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///blogs/detail/5705bcdf4a70& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&一大半上简历都是不合格的 @codeKK 开源站&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///blogs/detail/5705bcdf4a6f& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&推荐两个技术简历模板 @codeKK 开源站&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A//lucida.me/blog/lean-technical-resume/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&精益技术简历之道——改善技术简历的47条原则&i class=&icon-external&&&/i&&/a&&/li&&/ul&&br&&b&面试题&/b&&br&&ul&&li&&a href=&///?target=https%3A///JackyAndroid/AndroidInterview-Q-A& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&国内一线互联网公司内部面试题库&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=https%3A///GeniusVJR/LearningNotes& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 开发工程师面试指南&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A////%25E4%25B8%%25B8%25AA%25E4%25BA%%25B9%25B4Android%25E5%25BC%%258F%%E7%2599%25BE%25E5%25BA%25A6%25E3%E9%2598%25BF%25E9%E3%E8%E7%25BE%258E%25E3%E6%%25E5%25AE%25A2%25E7%259A%%259D%25A2%25E8%25AF%%25BF%%25BB%258F/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&一个五年Android开发者百度、阿里、聚美、映客的面试心经&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=https%3A///leerduo/InterviewQuestion& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&整理常见 Android 面试问题&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A//yuweiguocn.github.io//interview-2016-big-company/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&2016 Android 某公司面试题&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A///code//01/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&面试后的总结&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A///p/a& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android面试题整理&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=http%3A///Android-interview-questions-for-2-5-yrs-experienced& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android interview questions for 2-5 yrs experienced&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A///Android-interview-questions& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android interview questions&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=http%3A///essay/essayInfo/7195.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&40 个 Android 面试题&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=https%3A///Mr-YangCheng/ForAndroidInterview& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 名企面试题及涉及知识点整理&i class=&icon-external&&&/i&&/a&&/li&&/ul&&b&做题&/b&&br&&br&看完面试题之后那就来做一下面试题目吧, 目前找到两个网站&br&&ul&&li&&a href=&///?target=http%3A///android/interview-questions-and-answers& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&SillGun&i class=&icon-external&&&/i&&/a&(国外网站, 自备梯子)&br&&/li&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&牛客网-专业IT笔试面试备考平台&i class=&icon-external&&&/i&&/a&&br&&/li&&/ul&&br&&b&聊面试&/b&&br&&br&(帅张)&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&stormzhang&i class=&icon-external&&&/i&&/a& 跟你谈一下面试那些事儿&br&&ul&&li&&a href=&///?target=http%3A//mp./s%3F__biz%3DMzA4NTQwNDcyMA%3D%3D%26mid%3D%26idx%3D1%26sn%3Df8c1ca89a978f0e44cef%26scene%3D23%26srcid%3D08101MZAPzGR1MC1C577enim%23rd& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&面试时企业最看中你什么能力?&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/p/?refer=stormzhang& class=&internal&&我面试到底问什么?&/a&&/li&&li&&a href=&/p/?refer=stormzhang& class=&internal&&Android 面试那些事儿&/a&&/li&&/ul&&br&&b&知乎讨论&/b&&br&&ul&&li&&a href=&/question/& class=&internal&&面试时,问哪些问题能试出一个 Android 应用开发者真正的水平?&/a&&br&&/li&&li&&a href=&/question/& class=&internal&&我用个假简历去面试android的结果为什么会这样?&/a&&/li&&li&&a href=&/question/& class=&internal&&怎么准备Android面试?&/a&&/li&&/ul&&br&&b&互联网招聘平台&/b&&br&&ul&&li&&a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&拉勾网-最专业的互联网招聘平台&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=https%3A//jianxun.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&简寻-高端程序员精准职位推荐/精准招聘&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&100offer-高端人才招聘网站&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=https%3A///home/%23index& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Boss直聘&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&///?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LinkedIn (领英)&i class=&icon-external&&&/i&&/a&&br&&/li&&li&&a href=&///?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&哪上班-高质量互联网人才&i class=&icon-external&&&/i&&/a&&/li&&/ul&&b&感谢&/b&&br&&br&非常感谢上面分享面试资料以及面试经验的的前辈们!&br&有前辈在前面带路, 我们后辈真心感到幸福.&br&&br&&b&祝福&/b&&br&&br&最后祝正在找工作的的童鞋们, 马到成功, 心想事成, 事事如意!&br&&br&&b&关于我&/b&&br&&br&欢迎关注我 &a href=&///?target=https%3A///Freelander& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Freelander (G军仔) · GitHub&i class=&icon-external&&&/i&&/a& 以及 &a href=&///?target=http%3A///gaojunhuang& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&G军仔的微博&i class=&icon-external&&&/i&&/a&&br&&br&&b&如果感觉知乎的排版很难看,欢迎移步到 &a href=&///?target=http%3A///p/d1efe2f31b6d& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&简书&i class=&icon-external&&&/i&&/a&&/b&
在收藏的同时,麻烦顺手点个赞,谢谢啦!! 最近看到很多人都在找工作, 而且很多人都感觉今年找工作比去年难很多, 竞争力也增加不少, 因此激发我整理这份资料, 希望能帮到正在找或者准备找工作的童鞋们. 首先我们能否获得一个面试机会, 那肯定是从简历开始,…
我理解的全栈是这样的:&br&&br&1. 熟悉硅的提纯,以及晶体硅参杂的基本工艺。&br&2. 精通数字电路,模拟电路。精通 FPGA ,会自己流片。&br&3. 精通通信原理,数字信号处理。&br&4. 精通程序员的旧三大浪漫: 操作系统, 图形学, 编译原理&br&5. 精通程序员的新三大浪漫: 人工智能, 大数据,
AR/VR&br&6. 精通客户端开发, web 开发, 桌面开发, 熟练掌握一百种语言以及 API&br&7. last but not least, &b&精通 C++ &/b&
我理解的全栈是这样的: 1. 熟悉硅的提纯,以及晶体硅参杂的基本工艺。 2. 精通数字电路,模拟电路。精通 FPGA ,会自己流片。 3. 精通通信原理,数字信号处理。 4. 精通程序员的旧三大浪漫: 操作系统, 图形学, 编译原理 5. 精通程序员的新三大浪漫: 人工智…
谢 &a data-hash=&ad02ed87e3941cccc6bb1376581badc1& href=&///people/ad02ed87e3941cccc6bb1376581badc1& class=&member_mention& data-editable=&true& data-title=&@M.A.G.I& data-tip=&p$b$ad02ed87e3941cccc6bb1376581badc1& data-hovercard=&p$b$ad02ed87e3941cccc6bb1376581badc1&&@M.A.G.I&/a&邀请!最近比较忙,一直没时间刷直呼,这个点过来回答下! &a data-hash=&ad02ed87e3941cccc6bb1376581badc1& href=&///people/ad02ed87e3941cccc6bb1376581badc1& class=&member_mention& data-editable=&true& data-title=&@M.A.G.I& data-tip=&p$b$ad02ed87e3941cccc6bb1376581badc1& data-hovercard=&p$b$ad02ed87e3941cccc6bb1376581badc1&&@M.A.G.I&/a&说的很在理,跟团队有比较大的关系!&br&
刚来一个多月,但是感受还是挺多的!&br&&br&
1、我们BG刚进来是有mini项目的,几个应届生自由组队,七天时间搞出来一个app,这七天时间包括了idea筛选、竞品分析、需求调研、交互设计、视觉设计、产品研发、功能测试整个一套的研发流程,时间很短,压力还是比较大的。结束后回过头来看看,学到的东西还是很多的,技术上自然不用多说,通过跟队友讨论,你还有可能学到些产品分析和视觉设计方面的知识,甚至能在七天之内具备一些比较基础的视觉设计的能力,另外,由于时间很短,项目实施过程中对时间的高效管理也会有一些心得体会。当然最重要的是,认识了一群非常优秀的小伙伴,我跟 &a data-hash=&ad02ed87e3941cccc6bb1376581badc1& href=&///people/ad02ed87e3941cccc6bb1376581badc1& class=&member_mention& data-editable=&true& data-title=&@M.A.G.I& data-tip=&p$b$ad02ed87e3941cccc6bb1376581badc1& data-hovercard=&p$b$ad02ed87e3941cccc6bb1376581badc1&&@M.A.G.I&/a& 就是通过Mini项目认识的。&br&这里附上mini项目的应用宝地址,想玩玩的可以下载体验下:&a href=&///?target=http%3A///myapp/detail.htm%3FapkName%3Dcom.tencent.traveltrack& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&应用详情 - 应用宝官网&i class=&icon-external&&&/i&&/a&,时间太短,所以不能尽善尽美(估计与服务快到期了,服务端不知道现在已经下线了没)&br&&br&
2、现在在负责团队项目的构建脚本优化,其实是辅助一个T3来搞,由于项目太大,目前全编译一次要6分钟多,增量编译一次也要3分钟多,时间成本比较大。用脚本自动化构建是从13年初开始的,刚开始是直接用ADT搞定各种打包编译,13年初的时候遇到了dex方法数超过65536的问题,不得已而采用自动化构建,并做了分包处理,当时全国遇到这类问题的app应该不超过3个(当时折腾的时候各种倒腾系统源码,很多打包和构建工具,比如aapt是自己用系统源码重新编译出来的,而不是用Android自带的),在狼长某二线部门实习的时候,项目组的app代码已经七八十万行了,依然用ADT来构建,当然目前的Android5.0已经给出了分包机制。&br&&br&
3、大牛还是很多的,只是很多都没有写博客的习惯,即使写也只是发表在内网的km(上面很多内部员工写的非常好的技术文章,只是不能外泄)上,所以大家在开源社区里比较少能发现腾讯的大神,我之前发现了几个在一些开源社区比较活跃的,但是在内网上搜了下,也只是T2。当然写博客真的是一件有百利而无一害的事情的,如果有时间的话,多记录下技术或者生活上的一些心得还是挺好的。&br&&br&-----------------------------还有很多想写的,but太晚了,先睡了,明早还要上班----------------------------------&br&——————————————————update —————————————————-看来给自己挖坑了。好吧,过来补充下,虽然这个时候应该没什么人看了,但是自己挖的坑,总得填上。&br&&br&4、刚参加完小组的例会,虽然来了一个多月了,但是第一次参加小组例会,例会一般两周一次,之前每次都刚好有事,都没能参加。感觉分为还是很nice的,基本大家过一遍这两周的主要工作,讨论下技术,聊下生活,以及每次版本发布后去哪儿团建,貌似每段时间都会有技术分享(具体时间不是很清楚,也没问,这个小到几个小组,大到整个中心),因为今天例会,有同事在我们组内做了次分享的预演,具体内容就不细说了(不准外泄的),我感觉分享的内容还是挺有深度的,有些能听懂,有些就完全晕过去了。&br&&br&5、平台确实很好,不得不承认,整个项目中基本上会用到所有你能想到和你完全想不到的技术,不过要慢慢接触,慢慢吸收。km上有很多积淀下来的精华文章,基本都是同事们自已工作中遇到问题,然后自己分析、跟踪源码,总结出来的,有些在外面很难找到类似的。另外,内部也会有些自己些的工具,比如检测内存泄漏的工具,只是不对外开源。当然,最关键的还是看你能不能把资源利用好!&br&&br&6、代码相对比较规范,我这里说相对,因为工程越来越大,即使做过若干次重构,也避免不了一些地方的臃肿,但是这些规范绝对足够学习的了。&br&&br&7、身边的人都比较牛逼时,你就不得不逼着自己变得牛逼,圈子和氛围很重要,当然这里目前单指技术上。&br&&br&8、说点非技术上的吧!福利还是蛮多的,隔三差五就有些福利活动,什么中医问诊、免费游海洋馆、免费送水果、免费洗牙。。。只是有名额限制,抢满为止。其他福利不用说了吧,大家都知道的,每个月有Q币送,某些相关部门,每年都会有一两次送半年或一年的超级会员的活动,无息贷款升到了50W(以前没觉得有什么好的,但是最近跟组里同事聊买房的事情,才知道银行贷款虽然利息降到很低了,但是还是要多换很多),每年的大团建,有很多国外的线路可选,比如迪拜、日本、美国等等,只是超标准,自己要补贴不少,而且不能带女朋友,这个太坑。还有很好的一点,就是电影刚上映一两天,抢鲜版就出现在公司内网了,上映不到一周,高清版的就出来了!我每次都是拷了给同学看,不过自己基本没怎么看过!&br&&br&9、说点买房的事情吧!组里挺多同事都已经买房了,最蛋疼的是我导师就比我大两岁(本科出来就工作了),才工作四年多就升到T3了,房子都已经买了,2W一平米的,不过还房贷也挺苦逼的!&br&&br&好吧,扯的有点远了,其实进入bat就好比进入了名校,能给你光环,有更多的资源和更好的平台,但如果自己不努力,这一切就都是虚的,所以最终的发展还是要看自己。&br&&br&----------------------------扫描关注&b&“聚焦励志”&/b&微信公众账号,分享更多的励志故事------------------------------&br&&p&&a href=&///?target=http%3A///r/WkyxqdLEr4-QrZbK9xlI& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/r/WkyxqdL&/span&&span class=&invisible&&Er4-QrZbK9xlI&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& (二维码自动识别)&/p&
谢 邀请!最近比较忙,一直没时间刷直呼,这个点过来回答下! 说的很在理,跟团队有比较大的关系! 刚来一个多月,但是感受还是挺多的! 1、我们BG刚进来是有mini项目的,几个应届生自由组队,七天时间搞出来一个app,这七天时间包括了idea…
&p&看到这个问题忍不住要分享一点自己的想法。本人Google工作两年,入职之前也是前端后端摸个遍,单撸网站app从coding到deploy什么的都不在话下,所以找工作的时候也是在自己简历上写下了一笔Full stack engineer。&/p&&p&现在两年后回头再看觉得自己太天真了!都不用说全栈,就单单一个前端,吃不透的地方就太多太多了。跟当年自己玩的project不同,从工程的角度来开发一个项目,要考虑的事情真不一样。比如你用angular,乱watch会让UI变慢;写个api,可拓展性怎么样,迭代起来向后兼容性怎么样;你的style有考虑过从左向右的语言界面是什么样吗;一个函数,不给外部用的就一定要定义为私有的,不然将来想改它的时候还要到处搜有没有人用这个函数(虽然谷歌有code review,但这种code还是很常见);怎么debug test?怎么写前端的integration test?怎么写前端+后端的integration test?chrome console玩的够溜吗?考虑到后端那事情就更多了,数据库设计不好等PM提出一个feature的时候你可能就要用非常复杂,耗时的手段才能得到你想要的数据...所有这些单独拿出来都是个课题,都值得钻研。&/p&&p&所以我建议新人切忌贪多,先找家公司干着,自己去把坑踩一遍,然后去搜索成熟的解决方案,学习其背后的原理。这样渐渐的,你未必会成长为一个全栈工程师,但你一定会成为一个独当一面的工程师。祝好:)&/p&
看到这个问题忍不住要分享一点自己的想法。本人Google工作两年,入职之前也是前端后端摸个遍,单撸网站app从coding到deploy什么的都不在话下,所以找工作的时候也是在自己简历上写下了一笔Full stack engineer。现在两年后回头再看觉得自己太天真了!都不用…
认真的说。。。别买这书了。。书总是慢上好几拍的,真心想好好学学的话去看官方的文档,特别是初学者部分,英文不好就查字典看,查字典也不会的话就看国内翻译的版本也比书强多了。把上面的例子做一做,跑一跑。&br&----分割线---&br&由于有朋友问,初学者看官方文档真的能上手么?刚好手头有空就详细的说下吧,毕竟我自己当时是看官方文档入门的,而且当时还是09-10年之间,Dev Guide 远没有现在详细,现在的 Dev Guide 简直业界良心好嘛~哈哈,下面多图预警~~~&br&&br&打开官网 你会看到这样的 &a href=&///?target=http%3A///develop/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Develop Apps&i class=&icon-external&&&/i&&/a&&br&&img src=&/7a059fd3d486f2be5ec670f4b06836bb_b.png& data-rawwidth=&1248& data-rawheight=&586& class=&origin_image zh-lightbox-thumb& width=&1248& data-original=&/7a059fd3d486f2be5ec670f4b06836bb_r.png&&&br&我特地看了上面的四步,特别清晰明了&br&第一步 Set up Android Studio 教你怎么搭建环境,而且是最新的 Android Studio 哟,再也不用担心纠结 Eclipse 还是 Android Studio 了&br&点进去后是非常详细的 Android Studio 的说明书,从下载 IDE,如何编译,如何管理项目,如何发布,如何测试等等,还有一些常用功能介绍都有,左边是目录,右边是内容,截图如下,这部分是教你怎么玩 Android 的模拟器&br&&img src=&/627b04e65e8b1cfc695b21_b.png& data-rawwidth=&1309& data-rawheight=&580& class=&origin_image zh-lightbox-thumb& width=&1309& data-original=&/627b04e65e8b1cfc695b21_r.png&&&br&我们来看第二页 Build your first App &a href=&///?target=http%3A///training/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Getting Started&i class=&icon-external&&&/i&&/a&&br&这部分就是手把手写代码了,和很多书上的 Demo 类似,从怎么创建项目到加入一个 Activity 加入 Actionbar 等等,各种常用组建,还有面试必考 Android 四大金刚怎么用等等应有尽有,而且一步步深入浅出,非常适合完全没做过 Android 开发的人依样画葫芦的学习一遍 Android 开发流程。放一张 Activity 的图。&br&&br&&img src=&/3e6e74ff17abc779d26d7a0_b.png& data-rawwidth=&1279& data-rawheight=&586& class=&origin_image zh-lightbox-thumb& width=&1279& data-original=&/3e6e74ff17abc779d26d7a0_r.png&&&br&第三步是 Learn about android &a href=&///?target=http%3A///guide/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Introduction to Android&i class=&icon-external&&&/i&&/a&&br&其实这一步才是真正的 Android 介绍,我个人认为把 Android 详细的介绍放在这里是很合适的,经过上面两步,其实已经有个感性认识了,而且动手做过后肯定会有很多疑问。这部分就是各种详细的介绍,比如资源怎么管理加载, AndroidManifest 是什么鬼,国际化怎么做,传感器怎么玩等等。这部分其实是比较难啃的部分,可以先看一遍有个概念,后续遇到了具体问题再回来看会效果更好。&br&&img src=&/79324fbd9665edb49edb6997_b.png& data-rawwidth=&1224& data-rawheight=&620& class=&origin_image zh-lightbox-thumb& width=&1224& data-original=&/79324fbd9665edb49edb6997_r.png&&&br&第四步 Sample Projects &a href=&///?target=http%3A///samples/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Samples | Android Developers&i class=&icon-external&&&/i&&/a&&br&这个不用说了,就是一堆 Demo 大部分都提供了 Github 的库,很方便也很全面,从基本组件到动画到各种细节小功能或多或少都有一些。(早年就没几个 Demo 一看就看完了,现在好丰富了,我也建议遇到啥方面问题就去找啥方面 Demo 效果比较好)&br&&img src=&/dfe2dc61f9ac_b.png& data-rawwidth=&1251& data-rawheight=&632& class=&origin_image zh-lightbox-thumb& width=&1251& data-original=&/dfe2dc61f9ac_r.png&&&br&&br&&br&如此业界良心完整的官方文档不看真是太可惜了吧。而且更新速度和详细程度都是很多书籍无法比拟的,唯一的困扰大概就是英文吧,这个么,电脑现在都有划词翻译了,也不费事儿啊,是吧。
认真的说。。。别买这书了。。书总是慢上好几拍的,真心想好好学学的话去看官方的文档,特别是初学者部分,英文不好就查字典看,查字典也不会的话就看国内翻译的版本也比书强多了。把上面的例子做一做,跑一跑。 ----分割线--- 由于有朋友问,初学者看官…
&p&真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读Andoid系统源码,也包括阅读各种优秀的开源库。&/p&&br&&b&一、 阅读源码的准备&/b&&ol&&li&Java基础:上层framework以及App层都是采用Java语法;&br&&/li&&li&C/C++基础:Android的jni/native层代码采用C++,Linux 采用C;&br&&/li&&li&Linux:Android内核基于Linux的,了解Linux相关知识对深入掌握Android还是很有必要。&/li&&li&Git:Android源码采用git和repo进行管理;&/li&&li&Make:Android源码采用Make系统编译,源码系统中会看到很多Android.mk之类的文件;&/li&&li&Source Insight:这绝对是看源码的神器;可以在Java、C++、C代码之间无缝衔接;&/li&&li&Eclipse:熟悉常用快捷键,工欲善其事必先利其器;虽然Source Insight很方便,但由于对Eclipse的熟悉感,对于framework Java层面的代码,我还是更习惯用Eclipse来看,对于Native代码以及linux代码则采用Source Insight来看;&/li&&li&Android Studio:这是Google官方支持的App开发环境,关于Android Studiod使用教程;&/li&&li&Google Drawings:这是画图工具,Gityuan博客中的文章都是采用Google Drawing完成,比如&a href=&///?target=http%3A////binder-prepare/%23binder-1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Binder开篇&i class=&icon-external&&&/i&&/a&文中的图。&/li&&li&StarUML:这是类图,Gityuan博客文章的类图和流程图都是采用StarUML完成,比如&a href=&///?target=http%3A////app-process-create/%23forkandspecialize-1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&理解Android进程创建流程&i class=&icon-external&&&/i&&/a&文中时序图。&/li&&/ol&&b&二、 阅读源码的姿态&/b&&br&&br&&p&阅读源码绝不是从源码工程按顺序一个个的文件,从首行看到尾行。正确而高效地阅读源码的姿态应该是以某一个主线为起点,从上层往底层,不断地追溯,在各个模块、文件、方法之间来回跳转,反复地阅读,理清整个流程的逻辑。同时带着思考去看源码,尝试去揣测作者的用意,去理解代码的精妙之处,去思考代码可能存在的缺陷,去总结优秀的代码设计思想。下面说说我在阅读Android源码过程常涉及的库。&/p&&br&&p&&b&三、阅读Android源码&/b&&br&&/p&&br&&p&以Android开机过程为主线,展开一系列的文章 &a href=&///?target=http%3A///android/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android开篇&i class=&icon-external&&&/i&&/a&,如下图:&/p&&img src=&/509bfcda94f84079bcc9_b.jpg& data-rawwidth=&817& data-rawheight=&728& class=&origin_image zh-lightbox-thumb& width=&817& data-original=&/509bfcda94f84079bcc9_r.jpg&&&br&&br&&p&Android系统源码&a href=&///?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&&i class=&icon-external&&&/i&&/a&,这是Google官方源码,国内无法直接访问,需要翻墙,对于一个程序员来说具备翻墙的能力是非常有必要的。&/p&&p&Android源码中包含的库非常多,下面列举我在看Android源码过程中涉及比较多,也是比较常看的一些库:&br&&/p&&ul&&li&&a href=&///?target=https%3A///platform/packages/apps/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/platform/packages/apps&i class=&icon-external&&&/i&&/a&:Android自带的app,比如Email,Camera, Music等,对于应用开发工程师主要关注的目录;&br&&/li&&li&&a href=&///?target=https%3A///platform/frameworks/base/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/platform/frameworks/base&i class=&icon-external&&&/i&&/a&: Java framework,这是framework工程师看得最多的目录;&br&&/li&&li&&a href=&///?target=https%3A///platform/frameworks/native/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/platform/frameworks/native&i class=&icon-external&&&/i&&/a&:Native framework&br&&/li&&li&&a href=&///?target=https%3A///platform/art/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/platform/art&i class=&icon-external&&&/i&&/a&:Art虚拟机&/li&&li&&a href=&///?target=https%3A///kernel/common/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/kernel/common&i class=&icon-external&&&/i&&/a&:Android内核,这是驱动工程师最关注的模块;&br&&/li&&li&&a href=&///?target=https%3A///platform/system/core/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/platform/system/core&i class=&icon-external&&&/i&&/a& :核心系统&br&&/li&&li&&a href=&///?target=https%3A///platform/libcore/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&android/platform/libcore&i class=&icon-external&&&/i&&/a&:平台的lib库&/li&&/ul&&p&另外,对于无法翻墙的朋友来说,还可以通过 &a href=&///?target=https%3A///android& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&/android&i class=&icon-external&&&/i&&/a&下载Android源码,这是从Google官方源码的镜像同步而来的。&/p&&br&&b&四、 现有资源&/b&&br&&br&牛顿曾曰过一句名言:“如果我看得更远一点的话,是因为我站在巨人的肩膀上”,这句话很具有实用价值,千万不要一上来就一头扎进源码的世界,小心你会进入二次元世界,处于混沌状态,一定要合理利用现有资源。&p&Android 系统源码分析&/p&&ul&&li&&a href=&///?target=http%3A//blog.csdn.net/innost%3Fviewmode%3Dcontents& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Innost的专栏&i class=&icon-external&&&/i&&/a&&/li&&ul&&li&邓凡平前辈所写博客,条例有序,覆盖了Android系统大部分内容;&/li&&li&《深入理解Android》 (卷I,卷II,卷III)&br&&/li&&/ul&&li&&a href=&///?target=http%3A//blog.csdn.net/luoshengyang/article/details/8923485& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&老罗的Android之旅&i class=&icon-external&&&/i&&/a&:&/li&&ul&&li&罗升阳前辈所写博客,从各个层面介绍Android系统;&/li&&li&《Android系统源代码情景分析 》&/li&&/ul&&li&&a href=&///?target=http%3A///android/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Gityuan源码分析&i class=&icon-external&&&/i&&/a&&br&&/li&&ul&&li&对于邓凡平和罗升阳两位前辈的博客基于Android 2.x或4.x,目前Android已发展到Android 6.0。不管Android如何变化,其核心思维变化并没有很大,所以两位前辈的博客还是很有值得学习和参考的地方。话又说回来,Android经过了几个大版本的迭代,无论是从代码结构还是整体逻辑仍有不少变化。故博主计划写一关于Android 6.0源码系列的博文。&br&&/li&&li&&a href=&///?target=http%3A///gityuan& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Gityuan&i class=&icon-external&&&/i&&/a&作为Android界新秀,能力尚不及很多前辈,有一颗乐于分享的心,有一份痴于Android的品质,有一种坚持的态度,已经并还在努力奋斗的道路上...&/li&&/ul&&/ul&&br&-------------------------------------------------分割线-------------------------------------------------------------------&br&&br&&b&更多关于Android学习篇,见知乎文章 &a href=&/p/& class=&internal&&如何自学Android?&/a&&/b&
真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读Andoid系统源码,也包括阅读各种优秀的开源库。 一、 阅读源码的准备Java基础:上层framework以及App层都是采用Java语法; C/C++基础:Android的jni/native层代码采用C++,Linux 采用C; Linux:Android…
不知道你是不是指的纯技术方面的准备,如果是的话,我就提供一些拙见,大部分算是一些开发知识死角或者tips吧,权当抛砖引玉了:)&br&
下面的回答建立在JAVA基础(看着《JAVA核心技术 vol1》目录能梳理一遍JAVA常见知识点)和Android基础都过关的情况下。&br&一、JAVA SE&br&1、JAVA标准容器&br&
可能受一些网上流传的各种demo的影响,大多数Android开发者最拿手的就是ListView(RecycleView)+BaseAdapter+ArrayList三剑客,但是要知道ArrayList还有两个亲戚,一个是近亲CopyOnWriteArrayList,另外是远房LinkedList、CurrentHashMap。CopyOnWriteArrayList的效率比ArrayList略有下降,空间利用率也下降了很多,但是CopyOnWriteArrayList是线程安全的,CopyOnWriteArrayList和ArrayList对尾的操作都为O(1),但是其他位置的删除,插入操作很增加很大的时间复杂度,涉及到一次内存搬移过程,不过random access效率很高;LinkedList的随即插入和删除性能很高。&br&tips:数组复制,请使用System.arrayCopy或Arrays.copyOf 实现,且在JAVA中后者基于前者实现。&br&2、JAVA并发&br&
1、&b&ThreadPoolExecutor&/b&,JAVA并发的核心线程池框架,不过它的构造函数非常复杂:&br&&div class=&highlight&&&pre&&code class=&language-java&&&span class=&kd&&public&/span& &span class=&nf&&ThreadPoolExecutor&/span&&span class=&o&&(&/span&&span class=&kt&&int&/span& &span class=&n&&corePoolSize&/span&&span class=&o&&,&/span&
&span class=&kt&&int&/span& &span class=&n&&maximumPoolSize&/span&&span class=&o&&,&/span&
&span class=&kt&&long&/span& &span class=&n&&keepAliveTime&/span&&span class=&o&&,&/span&
&span class=&n&&TimeUnit&/span& &span class=&n&&unit&/span&&span class=&o&&,&/span&
&span class=&n&&BlockingQueue&/span&&span class=&o&&&&/span&&span class=&n&&Runnable&/span&&span class=&o&&&&/span& &span class=&n&&workQueue&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&this&/span&&span class=&o&&(&/span&&span class=&n&&corePoolSize&/span&&span class=&o&&,&/span& &span class=&n&&maximumPoolSize&/span&&span class=&o&&,&/span& &span class=&n&&keepAliveTime&/span&&span class=&o&&,&/span& &span class=&n&&unit&/span&&span class=&o&&,&/span& &span class=&n&&workQueue&/span&&span class=&o&&,&/span&
&span class=&n&&Executors&/span&&span class=&o&&.&/span&&span class=&na&&defaultThreadFactory&/span&&span class=&o&&(),&/span& &span class=&n&&defaultHandler&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&/code&&/pre&&/div&所以&b&有一个方便我们使用的工厂类,&/b&&b&Executors,可以创建4种类型的ThreadPool&/b&:&br&&ul&&li& 固定线程数量的线程池:Executors.newFixedThreadPool(int size);&/li&&li&单线程异步队列:Executors.newSingleThreadExecutor();&/li&&li&周期性调度:Executors.newSingleThreadScheduledExecutor();&/li&&li&多线程周期性调度:Executors.newScheduledThreadPool(1);&/li&&/ul&说到ThreadPoolExecutor的构造函数,它的最后一个参数BlockingQueue&Runnable&来自于包&b&java.util.concurrent&/b&,ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue和这个包里面其他的类也要过一遍。&br&&b&workQueue一定要用有界队列!&/b&设想一个极端情景,假设每个TaskWork都运行10s(更确切的说,IO等待10s),而ThreadPool在10s内接收到了1000个这样的TaskWork,如果我们使用了无界队列,队列的大小必然会急速增长直至进程Crash,但是如果我们使用了有界队列,假设队列长度为128,当TaskWork超过128,我们会有另外的线程帮忙处理,那系统的负载就可能降下来了。&br&
上面说到了任务池的创建,那里面的任务是什么?从哪儿来呢?里面的任务是&b&FutureTask&T&,&/b&构造函数的参数是一个Callable对象,而我们真正的任务就在Callable对象里面的call方法,FuterTask执行实际任务后会在主线程调用done函数,最后通过ExecutorService的submit方法将FutureTask提交到任务池。发一段伪代码:&br&&div class=&highlight&&&pre&&code class=&language-text&& public class SomeCallable implements Callable&String& {
public SomeCallable() {
public String call() throws Exception {
// some heavy work consting amounts of time
return &result&;
FutureTask&String& futureTask = new FutureTask&String&(new SomeCallable()) {
protected void done() {
String result = get();
//dosth to result
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(futureTask);
&/code&&/pre&&/div&
2、&b&一个线程sleep的小坑,我相信很多朋友都写过这样的代码:&/b&&br&&div class=&highlight&&&pre&&code class=&language-java&&&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&run&/span&&span class=&o&&()&/span& &span class=&o&&{&/span&
&span class=&k&&try&/span&&span class=&o&&{&/span&
&span class=&n&&Thread&/span&&span class=&o&&.&/span&&span class=&na&&sleep&/span&&span class=&o&&(&/span&&span class=&mi&&1000&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span& &span class=&k&&catch&/span& &span class=&o&&(&/span&&span class=&n&&InterruptedException&/span& &span class=&n&&ie&/span&&span class=&o&&){&/span&
&span class=&n&&ie&/span&&span class=&o&&.&/span&&span class=&na&&printStackTrace&/span&&span class=&o&&();&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&/code&&/pre&&/div&但是设想一下,如果我们的线程在执行sleep之前就被interrupt了呢,别以为不可能,ThreadPoolExecutor框架就是通过对所有的Thread进行interrupt来取消所有线程,这是我们上述代码就会抛出异常。所以良好的实践应该是:&br&&div class=&highlight&&&pre&&code class=&language-java&&&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&run&/span&&span class=&o&&()&/span& &span class=&o&&{&/span&
&span class=&k&&while&/span& &span class=&o&&(!&/span&&span class=&n&&Thread&/span&&span class=&o&&.&/span&&span class=&na&&currentThread&/span&&span class=&o&&().&/span&&span class=&na&&isInterrupted&/span&&span class=&o&&())&/span& &span class=&o&&{&/span&
&span class=&k&&try&/span&&span class=&o&&{&/span&
&span class=&n&&Thread&/span&&span class=&o&&.&/span&&span class=&na&&sleep&/span&&span class=&o&&(&/span&&span class=&mi&&1000&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span& &span class=&k&&catch&/span& &span class=&o&&(&/span&&span class=&n&&InterruptedException&/span& &span class=&n&&ie&/span&&span class=&o&&){&/span&
&span class=&n&&ie&/span&&span class=&o&&.&/span&&span class=&na&&printStackTrace&/span&&span class=&o&&();&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&/code&&/pre&&/div&
3、会用wait/notify来实现最简单的生产者-消费者模式。&a href=&///?target=http%3A//blog.csdn.net/monkey_d_meng/article/details/6251879& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&生产者/消费者问题的多种Java实现方式&i class=&icon-external&&&/i&&/a&&br&
4、&b&ThreadLocal变量的理解/定义&/b&。&b&ThreadLocal在Android中的应用&/b&,最典型的应用就是在android的messengeQueue-Looper模型中,Handler如何找到当前线程的Looper呢?我们平常直接在UI线程中new Handler()就可以了,里面就是mainLooper,但是Android怎么确定的UIx线程中new Handler()里面是mainLooper呢,答案就是通过将Looper作为ThreadLocal变量。以及&b&ThreadLocal基本的实现原理&/b&(在线程对象里面有一个inner static class)。&br&
5、JAVA的heap/stack的理解,可能会和多线程一起考察,&a href=&///?target=http%3A///2013/01/difference-between-stack-and-heap-java.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& 的页面&i class=&icon-external&&&/i&&/a&&br&
6、ConcurrentHashMap的实现,&a href=&///?target=http%3A///2013/02/concurrenthashmap-in-java-example-tutorial-working.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& 的页面&i class=&icon-external&&&/i&&/a&&br&
7、 JAVA的Reflection,Android内部很多东西都是基于Reflection实现,比如我们经常用的属性动画,就是通过属性名称找到属性的getter方法名,进而通过反射调用。不过对于日常开发的话,Reflection有两个作用,一是在一些情形下(特别是对属性的操作,包括更改、比较,比如我们可以定义一个通用的Collections.sort)可以提高代码复用度,二是可以做一些比较hack的事情,比如使用一些internal class,内部的AIDL等,修改一些internal类的static value。&br&二、Android&br&
1、&b&预防内存泄漏!擅用WeakReference&T&!&/b&&br&
所有从类外部传来的对象(特别对于Context,View,Fragmet,Activity对象),如果要将其放进类内部的容器对象或者静态类中引用,请一直用WeakReference包装!比如在TabLayout的源码中,在TabLayoutOnPageChangeListener中,就为TabLayout做了WeakReference wrap。&br&&img src=&/eee37ef20faeb_b.png& data-rawwidth=&773& data-rawheight=&131& class=&origin_image zh-lightbox-thumb& width=&773& data-original=&/eee37ef20faeb_r.png&&&br&
2、Android IPC,Binder的理解,&b&理解Binder的引用和实体&/b&,知道所谓的&b&客户端和服务端&/b&分别代表什么意思,懂得&b&ServiceManger&/b&对每个Service注册和根据服务名来getService的基本原理,这些没多少坑,但是非常庞杂,建议阅读《深入理解Android vol1》Chapter 6,&a href=&///?target=https%3A///subject/6802440/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&深入理解Android (豆瓣)&i class=&icon-external&&&/i&&/a&。&br&会写&b&AIDL&/b&,会用&b&Messenger&/b&夸进程传递信息,具体的实践:&a href=&///?target=http%3A//blog.csdn.net/hitlion2008/article/details/9773251& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android实战技术:IPC方式简介教程&i class=&icon-external&&&/i&&/a&。&br&
3、&b&Activity的简要&/b&&b&绘制(创建)过程 &/b&,Activity本质是为了Window(PhoneWindow)服务,&br&onAttach:&b&建立mwindow对象&/b&-&setContentView:&b&创建DecorView&/b&,在DecorView中根据Activity的风格来 创建Title(ActionBar),TitleContent(ActionBar下面的内容,内部资源id为android:id=&@android:id/content&)-&&b&mWindow.addView(mDecorView)&/b&,将创建好的DecorView添加进window,addview时创建一个RootView,也就是我们的R.layout.activity_main的母布局,&b&然后对子控件递归遍历发送绘图消息&/b&,子控件收到消息后 执行onMeasure-&onLayout-&onDraw,这时,我们就可以得到各控件的尺寸信息。&br&
4、 &b&在onCreate中获得视图的尺寸信息&/b&,注意到我们上面说,母控件通过遍历向子控件发送dispatchView信息来使子控件绘图,当然,我们也可以在&b&(setContentView)&/b&这之后在子控件上post一个Runnable到控件的runnable队列中去,在其中自然可以获得正确的尺寸。&br&
5、关于View的点点滴滴。&br&&b&基础:自定义单一View,换句话说,叫自定义UI,&/b&就是仅仅在OnDraw里面做了文章,比如仪表盘,圆形头像,自定义属性&br&&b&-&中级:自定义View与其他系统Wdiget协同工作,&/b&比如继承LinearLayout写一个自定义的TabLayout来与ViewPager协同工作,处理事件(滑动、点击、屏幕手势)分发,处理滑动事件冲突,这个阶段才可以被称之为自定义Widget&br&&b&-&进阶:突破Activity,直接向Window添加、删除、更新View,理解WindowManager仅仅是个引用,真正的工作在WindowManagerService里面完成。&/b&&br& 6、&b&图片加载框架,&/b&熟悉并实践过基本的缓存算法LruCache、DiskLruCache,对Bitmap重采样以降低OOM的几率,熟读一款中规中矩的图片加载框架如Universal Image Loader的源码,并能将各种策略总结。&br&
7、&b&SurfaceView的实践,&/b&SurfaceView最常见的一个使用情境是在我们的界面之上绘制各种动画,但是有一个问题,在布局发生改变时,SurfaceView会出现部分屏幕变黑的情况,包括但不限于在ViewPager、DrawerActivity中使用SurfaceView,需要知道这个问题的解决方案。&br&
7、熟练使用&b&ContentProvider&/b&,并懂得大概原理(很惭愧,我对Provider没做过深入理解)&br&
8、Activity的几种&b&FLAG和LauchMode&/b&分别代表的意义,以及使用场景。&br&
9、知道65535 dex-merge问题是怎么回事&br&
10、熟悉使用Android开发者选项功能,比如最常用的 布局边界显示、过度绘制检测、UI绘制速度检测、Surface更新时闪烁、严格模式、CPU利用率展示、不保持Activity。&br&三、拓展(上面这些都真正透了,就没有大的漏洞了)&br&
1、事件流编程,EventBus、RxJava。&br&
2、Kotlin语言。&br&
3、DataBinding,Google的这个MVVM框架实现的很完全,很强大,包括像Angular中自定义directive/filter的类似feature。&br&
4、知道Volley,okHttp他们的应用场景。&br&
5、熟悉一些ORM,包括现在新出的非基于SqlLite的数据库:Realm,&a href=&///?target=https%3A//realm.io& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Realm is a mobile database: a replacement for SQLite & Core Data&i class=&icon-external&&&/i&&/a&&br&
6、Android对Vector Icon的支持&br&
7、Android L新特性,Palette、CoordinatorLayout自定义Behavior等
不知道你是不是指的纯技术方面的准备,如果是的话,我就提供一些拙见,大部分算是一些开发知识死角或者tips吧,权当抛砖引玉了:) 下面的回答建立在JAVA基础(看着《JAVA核心技术 vol1》目录能梳理一遍JAVA常见知识点)和Android基础都过关的情况下。 一、…
&p&我们来先说一个常识性的错误:&/p&&br&&p&volley, retrofit, android-async-http 帮你封装了具体的请求,线程切换以及数据转换。&/p&&br&&p&而OkHttp 是基于http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的职责是一样的。&/p&&br&&p&所以不要混淆。&/p&&br&&p&-----以下纯个人主观见解&/p&&br&&p&首先,我想即使你单纯使用OkHttp,还是会再包一层的,这样就等价于Volley之流的框架,只是封装的好与坏而已。&/p&&br&&p&android-async-http内部实现是基于HttpClient, 想必你肯定知道6.0之后HttpClient是不是系统自带的了,不过它在最近的更新中将HttpClient的所有代码copy了一份进来,所以还能使用。&/p&&br&&p&Volley是官方出的,volley在设计的时候是将具体的请求客户端做了下封装:HurlStack,也就是说可以支持HttpUrlConnection, HttpClient, OkHttp,相当于模版模式吧,这样解耦还是非常方便的,可以随意切换,如果你之前使用过Volley,并习惯使用,那直接写个OkHttp扩展就行了。&/p&&br&&p&Retrofit因为也是square出的,所以大家可能对它更崇拜些。Retrofit的跟Volley是一个套路,但解耦的更彻底:比方说通过注解来配置请求参数,通过工厂来生成CallAdapter,Converter,你可以使用不同的请求适配器(CallAdapter), 比方说RxJava,Java8, Guava。你可以使用不同的反序列化工具(Converter),比方说json, protobuff, xml, moshi等等。&/p&&br&&p&炒鸡解耦,里面涉及到超多设计模式,个人觉得是很经典的学习案例。虽然支持Java8, Guava你可能也不需要用到。xml,protobuff等数据格式你也可能不需要解析。but,万一遇到鬼了呢。&/p&&p&至于性能上,个人觉得这完全取决于请求client,也就是okhttp的性能,跟这些封装工具没太大关系。&/p&&br&&p&至于RxJava,最好充分理解其原理之后再使用,别人云亦云,特别team人数多的情况下,总得有个完全精通的吧,万一掉坑里了呢。。。&/p&&br&&p&就说这么多啦,选最适合项目的,选大多数人选择的,选简单易用的,就这么个标准。&/p&&p&另外怎么选择开源library,可以参考我的简书 &a href=&///?target=http%3A///p/f& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这么多开源框架,该用哪个好?&i class=&icon-external&&&/i&&/a&&/p&&br&&p&------------&/p&&br&&p&额,为了更清晰的描述retrofit,Stay大致的分析了retrofit源码。&/p&&br&&p&流程图如下:&/p&&img src=&/3ee423f2ccb_b.png& data-rawwidth=&737& data-rawheight=&953& class=&origin_image zh-lightbox-thumb& width=&737& data-original=&/3ee423f2ccb_r.png&&&br&&br&&p&大家可以参考下。这么经典的设计模式示例,还是很少见的。&/p&&br&&p&详情可参见:&a href=&///?target=http%3A///p/45cb536be2f4& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Retrofit分析-漂亮的解耦套路&i class=&icon-external&&&/i&&/a&&/p&
我们来先说一个常识性的错误: volley, retrofit, android-async-http 帮你封装了具体的请求,线程切换以及数据转换。 而OkHttp 是基于http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的…
破百了,更新下BaseActivity和BaseFragment&br&&ol&&li&修改BaseActiviy的继承为Fragment(可以实现dialogfragment)&/li&&li&增加isDebug和APP_NAME,在Application中声明,方便日志打印,区分测试版本和正式版本&/li&&li&添加快速点击导致的各种问题。
&br&&/li&&/ol&PS:BaseActivit可以继承左滑返回的Activiy(&a href=&///?target=https%3A///ikew0ng/SwipeBackLayout& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GitHub - ikew0ng/SwipeBackLayout: An Android library that help you to build app with swipe back gesture.&i class=&icon-external&&&/i&&/a&),有需要的可以私信我,这里就不贴出来了。&br&&div class=&highlight&&&pre&&code class=&language-java&&&span class=&kd&&public&/span& &span class=&kd&&abstract&/span& &span class=&kd&&class&/span& &span class=&nc&&BaseActivity&/span& &span class=&kd&&extends&/span& &span class=&n&&FragmentActivity&/span& &span class=&kd&&implements&/span&
&span class=&n&&OnClickListener&/span& &span class=&o&&{&/span&
&span class=&cm&&/** 是否沉浸状态栏 **/&/span&
&span class=&kd&&private&/span& &span class=&kt&&boolean&/span& &span class=&n&&isSetStatusBar&/span& &span class=&o&&=&/span& &span class=&kc&&true&/span&&span class=&o&&;&/span&
&span class=&cm&&/** 是否允许全屏 **/&/span&
&span class=&kd&&private&/span& &span class=&kt&&boolean&/span& &span class=&n&&mAllowFullScreen&/span& &span class=&o&&=&/span& &span class=&kc&&true&/span&&span class=&o&&;&/span&
&span class=&cm&&/** 是否禁止旋转屏幕 **/&/span&
&span class=&kd&&private&/span& &span class=&kt&&boolean&/span& &span class=&n&&isAllowScreenRoate&/span& &span class=&o&&=&/span& &span class=&kc&&false&/span&&span class=&o&&;&/span&
&span class=&cm&&/** 当前Activity渲染的视图View **/&/span&
&span class=&kd&&private&/span& &span class=&n&&View&/span& &span class=&n&&mContextView&/span& &span class=&o&&=&/span& &span class=&kc&&null&/span&&span class=&o&&;&/span&
&span class=&cm&&/** 是否输出日志信息 **/&/span&
&span class=&kd&&private&/span& &span class=&kt&&boolean&/span& &span class=&n&&isDebug&/span&&span class=&o&&;&/span&
&span class=&kd&&private&/span& &span class=&n&&String&/span& &span class=&n&&APP_NAME&/span&&span class=&o&&;&/span&
&span class=&kd&&protected&/span& &span class=&kd&&final&/span& &span class=&n&&String&/span& &span class=&n&&TAG&/span& &span class=&o&&=&/span& &span class=&k&&this&/span&&span class=&o&&.&/span&&span class=&na&&getClass&/span&&span class=&o&&().&/span&&span class=&na&&getSimpleName&/span&&span class=&o&&();&/span&
&span class=&nd&&@Override&/span&
&span class=&kd&&protected&/span& &span class=&kt&&void&/span& &span class=&nf&&onCreate&/span&&span class=&o&&(&/span&&span class=&n&&Bundle&/span& &span class=&n&&savedInstanceState&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&kd&&super&/span&&span class=&o&&.&/span&&span class=&na&&onCreate&/span&&span class=&o&&(&/span&&span class=&n&&savedInstanceState&/span&&span class=&o&&);&/span&
&span class=&n&&isDebug&/span& &span class=&o&&=&/span& &span class=&n&&MApplication&/span&&span class=&o&&.&/span&&span class=&na&&isDebug&/span&&span class=&o&&;&/span&
&span class=&n&&APP_NAME&/span& &span class=&o&&=&/span& &span class=&n&&MApplication&/span&&span class=&o&&.&/span&&span class=&na&&APP_NAME&/span&&span class=&o&&;&/span&
&span class=&n&&$Log&/span&&span class=&o&&(&/span&&span class=&n&&TAG&/span& &span class=&o&&+&/span& &span class=&s&&&--&onCreate()&&/span&&span class=&o&&);&/span&
&span class=&k&&try&/span& &span class=&o&&{&/span&
&span class=&n&&Bundle&/span& &span class=&n&&bundle&/span& &span class=&o&&=&/span& &span class=&n&&getIntent&/span&&span class=&o&&().&/span&&span class=&na&&getExtras&/span&&span class=&o&&();&/span&
&span class=&n&&initParms&/span&&span class=&o&&(&/span&&span class=&n&&bundle&/span&&span class=&o&&);&/span&
&span class=&n&&mContextView&/span& &span class=&o&&=&/span& &span class=&n&&LayoutInflater&/span&&span class=&o&&.&/span&&span class=&na&&from&/span&&span class=&o&&(&/span&&span class=&k&&this&/span&&span class=&o&&)&/span&
&span class=&o&&.&/span&&span class=&na&&inflate&/span&&span class=&o&&(&/span&&span class=&n&&bindLayout&/span&&span class=&o&&(),&/span& &span class=&kc&&null&/span&&span class=&o&&);&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&mAllowFullScreen&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&this&/span&&span class=&o&&.&/span&&span class=&na&&getWindow&/span&&span class=&o&&().&/span&&span class=&na&&setFlags&/span&&span class=&o&&(&/span&
&span class=&n&&WindowManager&/span&&span class=&o&&.&/span&&span class=&na&&LayoutParams&/span&&span class=&o&&.&/span&&span class=&na&&FLAG_FULLSCREEN&/span&&span class=&o&&,&/span&
&span class=&n&&WindowManager&/span&&span class=&o&&.&/span&&span class=&na&&LayoutParams&/span&&span class=&o&&.&/span&&span class=&na&&FLAG_FULLSCREEN&/span&&span class=&o&&);&/span&
&span class=&n&&requestWindowFeature&/span&&span class=&o&&(&/span&&span class=&n&&Window&/span&&span class=&o&&.&/span&&span class=&na&&FEATURE_NO_TITLE&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&isSetStatusBar&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&steepStatusBar&/span&&span class=&o&&();&/span&
&span class=&o&&}&/span&
&span class=&n&&setContentView&/span&&span class=&o&&(&/span&&span class=&n&&mContextView&/span&&span class=&o&&);&/span&
&span class=&k&&if&/span& &span class=&o&&(!&/span&&span class=&n&&isAllowScreenRoate&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&setRequestedOrientation&/span&&span class=&o&&(&/span&&span class=&n&&ActivityInfo&/span&&span class=&o&&.&/span&&span class=&na&&SCREEN_ORIENTATION_LANDSCAPE&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span& &span class=&k&&else&/span& &span class=&o&&{&/span&
&span class=&n&&setRequestedOrientation&/span&&span class=&o&&(&/span&&span class=&n&&ActivityInfo&/span&&span class=&o&&.&/span&&span class=&na&&SCREEN_ORIENTATION_PORTRAIT&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&n&&initView&/span&&span class=&o&&(&/span&&span class=&n&&mContextView&/span&&span class=&o&&);&/span&
&span class=&n&&doBusiness&/span&&span class=&o&&(&/span&&span class=&k&&this&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span& &span class=&k&&catch&/span& &span class=&o&&(&/span&&span class=&n&&Exception&/span& &span class=&n&&e&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&e&/span&&span class=&o&&.&/span&&span class=&na&&printStackTrace&/span&&span class=&o&&();&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [沉浸状态栏]&/span&
&span class=&cm&&
&span class=&kd&&private&/span& &span class=&kt&&void&/span& &span class=&nf&&steepStatusBar&/span&&span class=&o&&()&/span& &span class=&o&&{&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&Build&/span&&span class=&o&&.&/span&&span class=&na&&VERSION&/span&&span class=&o&&.&/span&&span class=&na&&SDK_INT&/span& &span class=&o&&&=&/span& &span class=&n&&Build&/span&&span class=&o&&.&/span&&span class=&na&&VERSION_CODES&/span&&span class=&o&&.&/span&&span class=&na&&KITKAT&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&c1&&// 透明状态栏&/span&
&span class=&n&&getWindow&/span&&span class=&o&&().&/span&&span class=&na&&addFlags&/span&&span class=&o&&(&/span&
&span class=&n&&WindowManager&/span&&span class=&o&&.&/span&&span class=&na&&LayoutParams&/span&&span class=&o&&.&/span&&span class=&na&&FLAG_TRANSLUCENT_STATUS&/span&&span class=&o&&);&/span&
&span class=&c1&&// 透明导航栏&/span&
&span class=&n&&getWindow&/span&&span class=&o&&().&/span&&span class=&na&&addFlags&/span&&span class=&o&&(&/span&
&span class=&n&&WindowManager&/span&&span class=&o&&.&/span&&span class=&na&&LayoutParams&/span&&span class=&o&&.&/span&&span class=&na&&FLAG_TRANSLUCENT_NAVIGATION&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [初始化Bundle参数]&/span&
&span class=&cm&&
&span class=&cm&&
* @param parms&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kd&&abstract&/span& &span class=&kt&&void&/span& &span class=&nf&&initParms&/span&&span class=&o&&(&/span&&span class=&n&&Bundle&/span& &span class=&n&&parms&/span&&span class=&o&&);&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [绑定布局]&/span&
&span class=&cm&&
&span class=&cm&&
* @return&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kd&&abstract&/span& &span class=&kt&&int&/span& &span class=&nf&&bindLayout&/span&&span class=&o&&();&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [重写: 1.是否沉浸状态栏 2.是否全屏 3.是否禁止旋转屏幕]&/span&
&span class=&cm&&
&span class=&c1&&// public abstract void setActivityPre();&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [初始化控件]&/span&
&span class=&cm&&
&span class=&cm&&
* @param view&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kd&&abstract&/span& &span class=&kt&&void&/span& &span class=&nf&&initView&/span&&span class=&o&&(&/span&&span class=&kd&&final&/span& &span class=&n&&View&/span& &span class=&n&&view&/span&&span class=&o&&);&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [业务操作]&/span&
&span class=&cm&&
&span class=&cm&&
* @param mContext&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kd&&abstract&/span& &span class=&kt&&void&/span& &span class=&nf&&doBusiness&/span&&span class=&o&&(&/span&&span class=&n&&Context&/span& &span class=&n&&mContext&/span&&span class=&o&&);&/span&
&span class=&cm&&/** View点击 **/&/span&
&span class=&kd&&public&/span& &span class=&kd&&abstract&/span& &span class=&kt&&void&/span& &span class=&nf&&widgetClick&/span&&span class=&o&&(&/span&&span class=&n&&View&/span& &span class=&n&&v&/span&&span class=&o&&);&/span&
&span class=&nd&&@Override&/span&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&onClick&/span&&span class=&o&&(&/span&&span class=&n&&View&/span& &span class=&n&&v&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&fastClick&/span&&span class=&o&&())&/span&
&span class=&n&&widgetClick&/span&&span class=&o&&(&/span&&span class=&n&&v&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [页面跳转]&/span&
&span class=&cm&&
&span class=&cm&&
* @param clz&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&startActivity&/span&&span class=&o&&(&/span&&span class=&n&&Class&/span&&span class=&o&&&?&&/span& &span class=&n&&clz&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&startActivity&/span&&span class=&o&&(&/span&&span class=&n&&clz&/span&&span class=&o&&,&/span& &span class=&kc&&null&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [携带数据的页面跳转]&/span&
&span class=&cm&&
&span class=&cm&&
* @param clz&/span&
&span class=&cm&&
* @param bundle&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&startActivity&/span&&span class=&o&&(&/span&&span class=&n&&Class&/span&&span class=&o&&&?&&/span& &span class=&n&&clz&/span&&span class=&o&&,&/span& &span class=&n&&Bundle&/span& &span class=&n&&bundle&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&Intent&/span& &span class=&n&&intent&/span& &span class=&o&&=&/span& &span class=&k&&new&/span& &span class=&n&&Intent&/span&&span class=&o&&();&/span&
&span class=&n&&intent&/span&&span class=&o&&.&/span&&span class=&na&&setClass&/span&&span class=&o&&(&/span&&span class=&k&&this&/span&&span class=&o&&,&/span& &span class=&n&&clz&/span&&span class=&o&&);&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&bundle&/span& &span class=&o&&!=&/span& &span class=&kc&&null&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&intent&/span&&span class=&o&&.&/span&&span class=&na&&putExtras&/span&&span class=&o&&(&/span&&span class=&n&&bundle&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&n&&startActivity&/span&&span class=&o&&(&/span&&span class=&n&&intent&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&nd&&@SuppressWarnings&/span&&span class=&o&&(&/span&&span class=&s&&&unchecked&&/span&&span class=&o&&)&/span&
&span class=&kd&&public&/span& &span class=&o&&&&/span&&span class=&n&&T&/span& &span class=&kd&&extends&/span& &span class=&n&&View&/span&&span class=&o&&&&/span& &span class=&n&&T&/span& &span class=&nf&&$&/span&&span class=&o&&(&/span&&span class=&kt&&int&/span& &span class=&n&&resId&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&return&/span& &span class=&o&&(&/span&&span class=&n&&T&/span&&span class=&o&&)&/span& &span class=&kd&&super&/span&&span class=&o&&.&/span&&span class=&na&&findViewById&/span&&span class=&o&&(&/span&&span class=&n&&resId&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [含有Bundle通过Class打开编辑界面]&/span&
&span class=&cm&&
&span class=&cm&&
* @param cls&/span&
&span class=&cm&&
* @param bundle&/span&
&span class=&cm&&
* @param requestCode&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&startActivityForResult&/span&&span class=&o&&(&/span&&span class=&n&&Class&/span&&span class=&o&&&?&&/span& &span class=&n&&cls&/span&&span class=&o&&,&/span& &span class=&n&&Bundle&/span& &span class=&n&&bundle&/span&&span class=&o&&,&/span&
&span class=&kt&&int&/span& &span class=&n&&requestCode&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&Intent&/span& &span class=&n&&intent&/span& &span class=&o&&=&/span& &span class=&k&&new&/span& &span class=&n&&Intent&/span&&span class=&o&&();&/span&
&span class=&n&&intent&/span&&span class=&o&&.&/span&&span class=&na&&setClass&/span&&span class=&o&&(&/span&&span class=&k&&this&/span&&span class=&o&&,&/span& &span class=&n&&cls&/span&&span class=&o&&);&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&bundle&/span& &span class=&o&&!=&/span& &span class=&kc&&null&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&intent&/span&&span class=&o&&.&/span&&span class=&na&&putExtras&/span&&span class=&o&&(&/span&&span class=&n&&bundle&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&n&&startActivityForResult&/span&&span class=&o&&(&/span&&span class=&n&&intent&/span&&span class=&o&&,&/span& &span class=&n&&requestCode&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&nd&&@Override&/span&
&span class=&kd&&protected&/span& &span class=&kt&&void&/span& &span class=&nf&&onResume&/span&&span class=&o&&()&/span& &span class=&o&&{&/span&
&span class=&kd&&super&/span&&span class=&o&&.&/span&&span class=&na&&onResume&/span&&span class=&o&&();&/span&
&span class=&n&&$Log&/span&&span class=&o&&(&/span&&span class=&n&&TAG&/span& &span class=&o&&+&/span& &span class=&s&&&---&onResume()&&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&nd&&@Override&/span&
&span class=&kd&&protected&/span& &span class=&kt&&void&/span& &span class=&nf&&onDestroy&/span&&span class=&o&&()&/span& &span class=&o&&{&/span&
&span class=&kd&&super&/span&&span class=&o&&.&/span&&span class=&na&&onDestroy&/span&&span class=&o&&();&/span&
&span class=&n&&$Log&/span&&span class=&o&&(&/span&&span class=&n&&TAG&/span& &span class=&o&&+&/span& &span class=&s&&&---&onDestroy()&&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [是否允许全屏]&/span&
&span class=&cm&&
&span class=&cm&&
* @param allowFullScreen&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&setAllowFullScreen&/span&&span class=&o&&(&/span&&span class=&kt&&boolean&/span& &span class=&n&&allowFullScreen&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&this&/span&&span class=&o&&.&/span&&span class=&na&&mAllowFullScreen&/span& &span class=&o&&=&/span& &span class=&n&&allowFullScreen&/span&&span class=&o&&;&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [是否设置沉浸状态栏]&/span&
&span class=&cm&&
&span class=&cm&&
* @param allowFullScreen&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&setSteepStatusBar&/span&&span class=&o&&(&/span&&span class=&kt&&boolean&/span& &span class=&n&&isSetStatusBar&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&this&/span&&span class=&o&&.&/span&&span class=&na&&isSetStatusBar&/span& &span class=&o&&=&/span& &span class=&n&&isSetStatusBar&/span&&span class=&o&&;&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [是否允许屏幕旋转]&/span&
&span class=&cm&&
&span class=&cm&&
* @param isAllowScreenRoate&/span&
&span class=&cm&&
&span class=&kd&&public&/span& &span class=&kt&&void&/span& &span class=&nf&&setScreenRoate&/span&&span class=&o&&(&/span&&span class=&kt&&boolean&/span& &span class=&n&&isAllowScreenRoate&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&this&/span&&span class=&o&&.&/span&&span class=&na&&isAllowScreenRoate&/span& &span class=&o&&=&/span& &span class=&n&&isAllowScreenRoate&/span&&span class=&o&&;&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [日志输出]&/span&
&span class=&cm&&
&span class=&cm&&
* @param msg&/span&
&span class=&cm&&
&span class=&kd&&protected&/span& &span class=&kt&&void&/span& &span class=&nf&&$Log&/span&&span class=&o&&(&/span&&span class=&n&&String&/span& &span class=&n&&msg&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&isDebug&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&n&&Log&/span&&span class=&o&&.&/span&&span class=&na&&d&/span&&span class=&o&&(&/span&&span class=&n&&APP_NAME&/span&&span class=&o&&,&/span& &span class=&n&&msg&/span&&span class=&o&&);&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&span class=&cm&&/**&/span&
&span class=&cm&&
* [防止快速点击]&/span&
&span class=&cm&&
&span class=&cm&&
* @return&/span&
&span class=&cm&&
&span class=&kd&&private&/span& &span class=&kt&&boolean&/span& &span class=&nf&&fastClick&/span&&span class=&o&&()&/span& &span class=&o&&{&/span&
&span class=&kt&&long&/span& &span class=&n&&lastClick&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&&span class=&o&&;&/span&
&span class=&k&&if&/span& &span class=&o&&(&/span&&span class=&n&&System&/span&&span class=&o&&.&/span&&span class=&na&&currentTimeMillis&/span&&span class=&o&&()&/span& &span class=&o&&-&/span& &span class=&n&&lastClick&/span& &span class=&o&&&=&/span& &span class=&mi&&1000&/span&&span class=&o&&)&/span& &span class=&o&&{&/span&
&span class=&k&&return&/span& &span class=&kc&&false&/span&&span class=&o&&;&/span&
&span class=&o&&}&/span&
&span class=&n&&lastClick&/span& &span class=&o&&=&/span& &span class=&n&&System&/span&&span class=&o&&.&/span&&span class=&na&&currentTimeMillis&/span&&span class=&o&&();&/span&
&span class=&k&&return&/span& &span class=&kc&&true&/span&&span class=&o&&;&/span&
&span class=&o&&}&/span&
&span class=&o&&}&/span&
&/code&&/pre&&/div&&div class=&highlight&&&pre&&code class=&language-text&&public abstract class BaseFragment extends Fragment implements OnClickListener {
private boolean isD
private String APP_NAME;
protected final String TAG = this.getClass().getSimpleName();
private View mContextView =
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isDebug = MApplication.isD
APP_NAME = MApplication.APP_NAME;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mContextView = inflater.inflate(bindLayout(), container, false);
initView(mContextView);
doBusiness(getActivity());
return mContextV
* [绑定布局]
public abstract int bindLayout();
* [初始化控件]
* @param view
public abstract void initView(final View view);
* [业务操作]
* @param mContext
public abstract void doBusiness(Context mContext);
/** View点击 **/
public abstract void widgetClick(View v);
public void onClick(View v) {
if (fastClick())
widgetClick(v);
@SuppressWarnings(&unchecked&)
public &T extends View& T $(View view, int resId) {
return (T) view.findViewById(resId);
* [日志输出]
* @param msg
protected void $Log(String msg) {
if (isDebug) {
Log.d(APP_NAME, msg);
* [防止快速点击]
private boolean fastClick() {
long lastClick = 0;
if (System.currentTimeMillis() - lastClick &= 1000) {
lastClick = System.currentTimeMillis();
&/code&&/pre&&/div&
破百了,更新下BaseActivity和BaseFragment 修改BaseActiviy的继承为Fragment(可以实现dialogfragment)增加isDebug和APP_NAME,在Application中声明,方便日志打印,区分测试版本和正式版本添加快速点击导致的各种问题。 PS:BaseActivit可以继承左滑返回…
一个是响应速度,要保证界面之间跳转的时候没有延迟,也就是说要保证onClick之后,&br&1. 此Activity/Fragment的pause不会占用主线程太多时间&br&2. onClick事件里面不要写耗时的操作&br&3. 新的Activity的create、start、resume等生命周期函数不要占用太多时间&br&耗时操作可以等界面初始化好之后再去做,这样才能保证响应速度能达到用户可以接受的程度!&br&&br&另外一个是流畅性,这个就是说用户在某个界面操作的时候,不要出现卡顿(掉帧)的情况!这种情况比较复杂,所以要case by case地去解决!推荐用Systrace和Method Trace等性能工具来发现和排查!&br&&br&以上理论知识大家都懂,不过在实际开发中,情况要复杂的多,有的界面设计就很复杂,所以初始化就很慢,有的业务需求就是耗时,就是得在主线程里面去做……&br&所以其实也是一个博弈的过程,和设计人员博弈、和时间博弈(理论上时间可以搞定一切)、和需求博弈、和自己博弈!&br&&br&不过解决这种问题的流程一般不变:&br&1. 发现问题&br&2. 分析问题&br&3. 找到一个大家都能接受的解决办法&br&4. Fix&br&5. 以上等于没说
一个是响应速度,要保证界面之间跳转的时候没有延迟,也就是说要保证onClick之后, 1. 此Activity/Fragment的pause不会占用主线程太多时间 2. onClick事件里面不要写耗时的操作 3. 新的Activity的create、start、resume等生命周期函数不要占用太多时间 耗时…
Android开发者&br&&br&09年6月份去买的Android手机,09年底写出应用,随即加入创业公司至今.&br&&b&A. 眼界开阔&/b&&br&在做Android之前做的是银行外围业务,实在是厌恶了那种说话不算数,各方推诿责任的工作模式.几十人干了快一年,还没有人用过,挫败感太强了.接触Android后,差异感太大了.&br&&ol&&li&原来只用一周就可以完成一个小产品;&/li&&li&原来这个东西放出去还能挣钱;&/li&&li&原来有很多人对你的产品感兴趣,并给出各种意见.&br&&/li&&li&原来你也可以说,这个意见俺就是不接受.&/li&&li&原来创业公司可以这样起步,几个人,租个小两居.&/li&&li&原来团队开发可以如此高效.&/li&&li&原来想法可以如此的多,且大家的想法有如此多的交集.&/li&&li&原来别人也想到这个,并且比我们还先动手.&/li&&li&原来很多想法都如此的浅薄,禁不起推敲.&/li&&li&原来我们做的东西也可以Top 1.&/li&&li&原来有如此多的创业团队,会有Bump,Path,Flipboard这么精致的产品.&/li&&li&原来社区产品的运营很重要,用户个性的多样化,完全不按你规定的路线出牌&/li&&li&原来我必须对多样化的用户需求进行筛选,排级,剔除.叫的最响的不一定是最有用的需求&/li&&li&原来用户需要引导,用户也有反击.&/li&&/ol&&b&B. 自我约束&/b&&br&这点收获也很大,创业公司,不规定你什么时候上下班,不规定你什么时候出活,没人明确的指定你要做成什么样.但大家都在一起工作,每天工作内容,质量,数量.大家都一清二楚.你需要:&ol&&li&自己去定开发计划,清楚自己在做什么.&br&&/li&&li&自己去保证开发效率,当你在做自己的产品的时候,这种动力是油然而生的.&/li&&li&自己保证开发质量,作为小牛代码质量这个是基本功;UI/UE 也得努力学,不落后.&/li&&/ol&&b&C. 学会规划&/b&&br&规划时间,规划产品,规划职业.学会一种方法.XY法.X轴代表你学习的广度,Y轴代表你学习的深度.&br&比如想成为Android开发高手:&br&X轴可以有:基础组件的使用,framework架构,设计模式,UI/UE&br&Y轴可以有:基础组件能够自定义,framework的源码深入阅读,设计模式的熟练使用,UI/UE的领悟.&br&&br&这样你就可以很容易看出自己的方向,可以偏产品一点,那么UI/UE到什么程度,偏技术一些framework的源码阅读到什么程度.&br&&br&&b&D. 这是一个团队&/b&&br&学会协同工作,使用一些工具,google Doc,Trac,git等;定期做技术交流;定期做水果分享.达到知识共享.共同进步.
Android开发者 09年6月份去买的Android手机,09年底写出应用,随即加入创业公司至今. A. 眼界开阔 在做Android之前做的是银行外围业务,实在是厌恶了那种说话不算数,各方推诿责任的工作模式.几十人干了快一年,还没有人用过,挫败感太强了.接触Android后,差异感…
&ul&&li&个人比较推荐Square开源组合,用Retrofit(目前已经是2.0+)+OkHttp基本上已经可以处理任何业务场景了,Square开源库质量还是值得信赖的。&br&&/li&&/ul&Retrofit的特点我个人认为是简化了网络请求流程,同时自己内部对OkHtttp客户端做了封装,同时2.x把之前1.x版本的部分不恰当职责都转移给OkHttp了(例如Log,目前用OkHttp的Interceptor来实现),这样的好处是职责清晰,Retrofit做自己该做的事儿。&br&&br&而且Retrofit提供不同的Json Converter实现(也可以自定义),同时提供RxJava支持(返回Observable对象),配合Jackso

我要回帖

更多关于 面试时应该问哪些问题 的文章

 

随机推荐