注入解放双手,用好一些插件比如butterKnife能省去很多findViewById的麻烦;
用好属性动画,看过很多App,引导页带动画的给人第一印象就很好,毕竟这是一个看“脸”的时代;
虽然App设计风格一直都是IOS,还是要支持MaterialDesign,毕竟很 cool,现在市面上这样风格的还是比较少;
熟悉android-support-v7-21新组件包,比如RecycleView、DrawerLayout、CardView等等都已经有很高使用率;
布局复杂导致的性能问题不容小觑,多看一些相关知识,精简布局;
2.图片方面:
最喜欢Picasso,尤其是管道式的调用,编程之美啊;
而且Picasso还可以支持高斯模糊,太方便了;
3.网络方面:
现在的趋势基本上都是okHttp + retrofit,还好之前实习的时候师兄用的就是这个,感觉还是很方便的;
retrofit的风格好像是传说中的REST,下阶段需要看看源码;
图片上传是个问题;
4.第三方:
现在的App基本都要有这些功能:.分享、支付、定位、推送、统计、buggly、第三方登录,我只用过高德定位和百度定位、极光推送、友盟推送也只是负责埋点,还没了解完整流程。下一阶段需要统统使用一次。
在项目过程中还发现一个问题,在A项目中集成了分享的Module,结果导入到B中还是有问题,结果还得需要一个人重新集成一次,效率不高。需要注意不要实现功能就算了,要提成一个单独的、可插拔的Module,写好回调,做到一键集成。
5.工具方面:
AndroidStudio还是很强大的,很多细小的功能点需要我们花时间去发现,比如说内存使用监控、截屏、gif录制、当前git分支名称等等都可以找到,不了解的话太可惜了,国内有个镜像网站可以直接更新SDK,很强大http://www.androiddevtools.cn/
Gradle真是个神奇的东西,又能构建、又能依赖更新、还能多渠道打包,需要好好看看;Gradle官方文档
Git现在公司使用率还是比较高的,使用不好,同步时各种问题太蛋疼,有效使用能在development和release版本间实现良好控制、友好协作;Git详解
Maven 这个是因为身边人基本都会,好像在项目管理、减少本地代码方面有很大作用,需要学习学习;
6.工具类方面:
做个2个商业项目 ,发现工具类基本都是通用的,所以有必要维护自己的工具类,工具类的内容包括且不限于:
本地缓存类、文件管理类、Json处理类、日志类、网络情况类、字符串类、手机系统信息类、线程池类、常用的UI类、6.0以后还需要权限类(用于动态提示用户是否提供某权限)等等等等,遇到新功能就添进去,这就是自己的行走江湖的利器之一啊。
7.架构方面:
其实我是拒绝谈架构的,毕竟我还是只小菜鸟。但是最近项目要更换MVP架构,我也学了学,发现了一个重要的问题—–>要想懂新架构的好旧架构的差,不学点设计模式是不行的。所以设计模式是下一阶段的重要任务。
MVP现在我还理解不太深,还是先做好第一步吧:减轻Activity任务,把点击响应尽量放到自定义View或者Fragment里;
一说架构、性能,就得考虑线程管理方面的东西,虽然我现在接触的不多,但是好的应用要经得起高并发才对,所以这也不能忘记。
8.渠道发布:
每个App上线的毕竟之路就是打包、发布,鉴于国内应用市场杂乱,多达900+个市场,如果没有很好的打包方式,一个个打岂不是累死。好在现在gradle打包很强大,不过我也只是听说,还没有亲手接触过,需要先学好Gradle,然后体会体会它的便捷啊!
two,学会使用Android开发的书籍,教程,工具
入门书籍
《Google Androidsdk揭秘》
《Learning Android(中文版)》
本书为Android开发入门图书,循序渐进地介绍了如何利用Android基本构件来实现构造用户界面、存储数据、连接网络等实践中必不可少的需求。作者以亲手实现一个类Twitter的应用为主线,通过不断为其添加功能展开讲解。而这一学习过程积累出的代码模式库,可以灵活运用于真实Android应用开发。本书内容包括但不限于:Android平台概览、Android设计架构、Android开发环境配置、基本Android的用户界面构建、UI元件组织方法、构建执行后台任务与更新数据的服务、AIDL与NDK介绍等。
《Android疯狂讲义》
课程涵盖全部Android应用开发的基础,根据技能点的作用分为5个篇章,包括环境篇、控件篇、布局篇、组件篇和通用篇,本课程的目标就是“看得懂、学得会、做得出”,为后续的学习打下夯实的基础。
《密西西比河谷州立大学:Android应用程序开发(英文视频,中文字幕)》
课程介绍基于Android平台上的应用开发,课程分为六个模块,分别涉及Android平台概述和其基本构件、初次编写Android应用程序及接收和显示网络数据等内容。通过本课程,你将很好地了解Android平台,了解如何运用Android平台,以及进一步研究该平台的学习方向。
《Android攻城狮》
课程由浅入深地带您学会Android的常用控件的开发和使用,以知识概念为主导,实例代码为驱动,带您走入一个神奇的移动开发世界。
课程讲带你熟悉Android开发中常用的调试方式,各种对话框,各种提示菜单,各种动画效果等,来进一步充实你的Android知识。
《Android的设计与实现:卷1》
本书是Android应用开发工程师和Android系统工程师进阶修炼的必读之作。它由资深Android内核专家亲自执笔,从源代码角度,系统、深入、透彻剖析Android系统框架层(Framework)的设计思想和实现原理,为Android应用工程师和系统工程师解决实际工作中的各种难题提供了原理性的指导。为了降低读者的阅读成本,《Android的设计与实现:卷1》使用了大量简单的UML类图和序列图来展示类的层次结构和方法的调用流程,使读者能迅速读完《Android的设计与实现:卷1》并领会其精髓!
《深入理解Android:卷1》
这是一本以情景方式对Android的源代码进行深入分析的书。内容广泛,以对Framework层的分析为主,兼顾Native层和Application层;分析深入,每一部分源代码的分析都力求透彻;针对性强,注重实际应用开发需求,书中所涵盖的知识点都是Android应用开发者和系统开发者需要重点掌握的。
《深入理解Android:卷2》
“深入理解Android”系列的第2本,第1本书上市后获得广大读者高度评价,在Android开发者社群内口口相传。《深入理解Android:卷2》不仅继承了第1本书的优点并改正了其在细微处存在的一些不足,而且还在写作的总体思想上进行了创新,更强调从系统设计者的角度去分析Android系统中各个模块内部的实现原理和工作机制。从具体内容上讲,重点是Android Framework的Java层,对Java层涉及的核心模块和服务进行了深入而细致的分析。通过《深入理解Android:卷2》,读者不仅能对Android系统本身有更深入的理解,而且还能掌握分析大型复杂源代码的能力。
《Android应用性能优化》
今天的Android应用开发者经常要想尽办法来提升程序性能。由于应用越来越复杂,这个问题也变得越来越棘手。《Android应用性能优化》主要介绍如何快速高效地优化应用,让应用变得稳定高效,你将学会利用Android SDK和NDK来混合或单独使用Java、C/C++来开发应用。《Android应用性能优化中还特别讲解了如下内容:一些OpenGL的优化技术以及RenderScript(Android的新特性)的基础知识;利用SDK来优化应用的Java代码的技巧;通过高效使用内存来提升性能的技巧;延长电池使用时间的技巧;使用多线程的时机及技巧;评测剖析代码的技巧。
《Android软件安全与逆向分析》
由浅入深、循序渐进地讲解了Android系统的软件安全、逆向分析与加密解密技术。包括Android软件逆向分析和系统安全方面的必备知识及概念、如何静态分析Android软件、如何动态调试Android软件、Android软件的破解与反破解技术的探讨,以及对典型Android病毒的全面剖析。
官方资源
Android开发者中心
Android开发官方文档。这个不必多说了。
《Android 设计指南(官方英文版))》(非官方简体中文版 )
指导你设计一款Android应用。内容涉及:Android应用设计原则、UI概览、风格、模式和控件设计方面。
技术问答
Stack Overflow。Stack Overflow Android的标签页包括很完整的信息,很有参考价值!
周刊和聚合
Android周刊(英文) (中文)
每周更新的Android开发周刊。内容包括:开发资讯、技术文章、App设计、工具等。
Android开发话题
伯乐头条的Android开发话题聚合了很多Android开发相关的文章、教程、资讯等。内容来自Android原创技术博客作者或者读者分享,伯乐在线安卓频道团队整理。这个话题即将提供订阅功能,关注话题后即可收到每周推送精选内容推送。
工具和开发库
Android开源工具和库
GitHub上最热门的Android开源工具和开发库。
Android开发工具(中文)
由伯乐在线安卓开发频道团队整理。持续更新各种优秀的Android开发工具。
其实Android的书籍很多,最基本的是掌握Android按钮的代码功能实现,其次多看看安卓巴士网站的代码
三,Android常用代码片段
1
2
3
4
5
6
7
8
9
|
publicstaticintdip2px(Context context, floatdpValue) {
finalfloatscale = context.getResources().getDisplayMetrics().density;
return(int) (dpValue * scale + 0.5f);
}
publicstaticintpx2dip(Context context, floatpxValue) {
finalfloatscale = context.getResources().getDisplayMetrics().density;
return(int) (pxValue / scale + 0.5f);
}
|
1
2
3
4
5
6
7
8
9
|
publicstaticintpx2sp(Context context, floatpxValue) {
finalfloatfontScale = context.getResources().getDisplayMetrics().scaledDensity;
return(int) (pxValue / fontScale + 0.5f);
}
publicstaticintsp2px(Context context, floatspValue) {
finalfloatfontScale = context.getResources().getDisplayMetrics().scaledDensity;
return(int) (spValue * fontScale + 0.5f);
}
|
格式为小时/分/秒/毫秒(如:24903600 –> 06小时55分03秒600毫秒)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/**
* @param millis
* 要转化的毫秒数。
* @param isWhole
* 是否强制全部显示小时/分/秒/毫秒。
* @param isFormat
* 时间数字是否要格式化,如果true:少位数前面补全;如果false:少位数前面不补全。
* @return 返回时间字符串:小时/分/秒/毫秒的格式(如:24903600 --> 06小时55分03秒600毫秒)。
*/
publicstaticString millisToString(longmillis, booleanisWhole,
booleanisFormat) {
String h = "";
String m = "";
String s = "";
String mi = "";
if(isWhole) {
h = isFormat ? "00小时": "0小时";
m = isFormat ? "00分": "0分";
s = isFormat ? "00秒": "0秒";
mi = isFormat ? "00毫秒": "0毫秒";
}
longtemp = millis;
longhper = 60* 60* 1000;
longmper = 60* 1000;
longsper = 1000;
if(temp / hper > 0) {
if(isFormat) {
h = temp / hper < 10? "0"+ temp / hper : temp / hper + "";
} else{
h = temp / hper + "";
}
h += "小时";
}
temp = temp % hper;
if(temp / mper > 0) {
if(isFormat) {
m = temp / mper < 10? "0"+ temp / mper : temp / mper + "";
} else{
m = temp / mper + "";
}
m += "分";
}
temp = temp % mper;
if(temp / sper > 0) {
if(isFormat) {
s = temp / sper < 10? "0"+ temp / sper : temp / sper + "";
} else{
s = temp / sper + "";
}
s += "秒";
}
temp = temp % sper;
mi = temp + "";
if(isFormat) {
if(temp < 100&& temp >= 10) {
mi = "0"+ temp;
}
if(temp < 10) {
mi = "00"+ temp;
}
}
mi += "毫秒";
returnh + m + s + mi;
}
|
格式为小时/分/秒/毫秒(如:24903600 –> 06小时55分03秒)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
/**
*
* @param millis
* 要转化的毫秒数。
* @param isWhole
* 是否强制全部显示小时/分/秒/毫秒。
* @param isFormat
* 时间数字是否要格式化,如果true:少位数前面补全;如果false:少位数前面不补全。
* @return 返回时间字符串:小时/分/秒/毫秒的格式(如:24903600 --> 06小时55分03秒)。
*/
publicstaticString millisToStringMiddle(longmillis, booleanisWhole,
booleanisFormat) {
returnmillisToStringMiddle(millis, isWhole, isFormat, "小时", "分钟", "秒");
}
publicstaticString millisToStringMiddle(longmillis, booleanisWhole,
booleanisFormat, String hUnit, String mUnit, String sUnit) {
String h = "";
String m = "";
String s = "";
if(isWhole) {
h = isFormat ? "00"+ hUnit : "0"+ hUnit;
m = isFormat ? "00"+ mUnit : "0"+ mUnit;
s = isFormat ? "00"+ sUnit : "0"+ sUnit;
}
longtemp = millis;
longhper = 60* 60* 1000;
longmper = 60* 1000;
longsper = 1000;
if(temp / hper > 0) {
if(isFormat) {
h = temp / hper < 10? "0"+ temp / hper : temp / hper + "";
} else{
h = temp / hper + "";
}
h += hUnit;
}
temp = temp % hper;
if(temp / mper > 0) {
if(isFormat) {
m = temp / mper < 10? "0"+ temp / mper : temp / mper + "";
} else{
m = temp / mper + "";
}
m += mUnit;
}
temp = temp % mper;
if(temp / sper > 0) {
if(isFormat) {
s = temp / sper < 10? "0"+ temp / sper : temp / sper + "";
} else{
s = temp / sper + "";
}
s += sUnit;
}
returnh + m + s;
}
|
把一个毫秒数转化成时间字符串。格式为小时/分/秒/毫秒(如:24903600 –> 06小时55分钟)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
/**
*
* @param millis
* 要转化的毫秒数。
* @param isWhole
* 是否强制全部显示小时/分。
* @param isFormat
* 时间数字是否要格式化,如果true:少位数前面补全;如果false:少位数前面不补全。
* @return 返回时间字符串:小时/分/秒/毫秒的格式(如:24903600 --> 06小时55分钟)。
*/
publicstaticString millisToStringShort(longmillis, booleanisWhole,
booleanisFormat) {
String h = "";
String m = "";
if(isWhole) {
h = isFormat ? "00小时": "0小时";
m = isFormat ? "00分钟": "0分钟";
}
longtemp = millis;
longhper = 60* 60* 1000;
longmper = 60* 1000;
longsper = 1000;
if(temp / hper > 0) {
if(isFormat) {
h = temp / hper < 10? "0"+ temp / hper : temp / hper + "";
} else{
h = temp / hper + "";
}
h += "小时";
}
temp = temp % hper;
if(temp / mper > 0) {
if(isFormat) {
m = temp / mper < 10? "0"+ temp / mper : temp / mper + "";
} else{
m = temp / mper + "";
}
m += "分钟";
}
returnh + m;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
/**
* @param millis
* 要转化的日期毫秒数。
* @param pattern
* 要转化为的字符串格式(如:yyyy-MM-dd HH:mm:ss)。
* @return 返回日期字符串。
*/
publicstaticString millisToStringDate(longmillis, String pattern) {
SimpleDateFormat format = newSimpleDateFormat(pattern,
Locale.getDefault());
returnformat.format(newDate(millis));
}
|
1
2
3
4
5
6
7
8
9
10
11
|
/**
* @param millis
* 要转化的日期毫秒数。
* @param pattern
* 要转化为的字符串格式(如:yyyy-MM-dd HH:mm:ss)。
* @return 返回日期字符串(yyyy_MM_dd_HH_mm_ss)。
*/
publicstaticString millisToStringFilename(longmillis, String pattern) {
String dateStr = millisToStringDate(millis, pattern);
returndateStr.replaceAll("[- :]", "_");
}
|
1小时内用,多少分钟前; 超过1小时,显示时间而无日期; 如果是昨天,则显示昨天 超过昨天再显示日期; 超过1年再显示年。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
publicstaticlongoneHourMillis = 60* 60* 1000; // 一小时的毫秒数
publicstaticlongoneDayMillis = 24* oneHourMillis; // 一天的毫秒数
publicstaticlongoneYearMillis = 365* oneDayMillis; // 一年的毫秒数
publicstaticString millisToLifeString(longmillis) {
longnow = System.currentTimeMillis();
longtodayStart = string2Millis(millisToStringDate(now, "yyyy-MM-dd"),
"yyyy-MM-dd");
// 一小时内
if(now - millis <= oneHourMillis && now - millis > 0l) {
String m = millisToStringShort(now - millis, false, false);
return"".equals(m) ? "1分钟内": m + "前";
}
// 大于今天开始开始值,小于今天开始值加一天(即今天结束值)
if(millis >= todayStart && millis <= oneDayMillis + todayStart) {
return"今天 "+ millisToStringDate(millis, "HH:mm");
}
// 大于(今天开始值减一天,即昨天开始值)
if(millis > todayStart - oneDayMillis) {
return"昨天 "+ millisToStringDate(millis, "HH:mm");
}
longthisYearStart = string2Millis(millisToStringDate(now, "yyyy"),
"yyyy");
// 大于今天小于今年
if(millis > thisYearStart) {
returnmillisToStringDate(millis, "MM月dd日 HH:mm");
}
returnmillisToStringDate(millis, "yyyy年MM月dd日 HH:mm");
}
|
1
2
3
4
5
6
7
8
9
10
11
|
publicstaticlongstring2Millis(String str, String pattern) {
SimpleDateFormat format = newSimpleDateFormat(pattern,
Locale.getDefault());
longmillis = 0;
try{
millis = format.parse(str).getTime();
} catch(ParseException e) {
Log.e("TAG", e.getMessage());
}
returnmillis;
}
|
1
|
publicstaticfinalString REG_PHONE_CHINA = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
|
最后一点,就是使用Android测试工具,会测试Android程序bug更好,公司不想花钱请测试人员,Java程序使用junit测试工具,Android呢?----UI antomator,appium,monkeyrunner等Android测试工具.
最后一点,就是感谢上帝,共享源代码
|
end adiOS |