├── Android ├── Gradle │ ├── 1_Gradle脚本基础(Android).md │ ├── 2_Gradle语法基础解析.md │ ├── 3_ProGuard基础语法和打包配置.md │ ├── 4_AndroidStudio下ProGuard混淆打包.md │ ├── 5_Gradle多渠道和自动化打包(基础篇).md │ ├── 6_Gradle多渠道和自动化打包(深入篇).md │ ├── README.md │ └── 电子书 │ │ ├── Building_and_Testing_with_Gradle.pdf │ │ └── userguide.pdf ├── README.md ├── 个人收藏 │ ├── README.md │ └── 如何查看aar的源代码.md ├── 图片处理 │ ├── 01_各大图片加载框架的使用汇总.md │ └── README.md ├── 实现原理 │ └── README.md ├── 性能优化 │ ├── 01_Android系统那些重要的LOG.md │ └── README.md └── 辅助工具 │ ├── AndroidStudio插件系列.md │ ├── Android反编译工具系列.md │ ├── Android性能分析工具整理汇总.md │ └── README.md ├── Chrome └── README.md ├── Code ├── Android编码命名规范.md └── README.md ├── Git └── README.md ├── IM └── README.md ├── JavaWeb ├── 00_服务器开发学习计划.md └── README.md ├── LICENSE ├── README.md └── Team └── README.md /Android/Gradle/1_Gradle脚本基础(Android).md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-clock/Doc/1e2f29faba683344eff3893a1c5e936ddfd52dea/Android/Gradle/1_Gradle脚本基础(Android).md -------------------------------------------------------------------------------- /Android/Gradle/2_Gradle语法基础解析.md: -------------------------------------------------------------------------------- 1 | # Gradle语法基础解析 2 | 3 | 在从ADT转移到AndroidStudio下开发,必然会遇到Gradle脚本打包的问题.看懂一个脚本最基本的前提就是了解它的语法,我在转移开发环境的过程中,也开始接触学习Gradle,在此做了一些总结,方便自己查阅. 4 | 5 | ## Gradle为何物 6 | 7 | 第一次接着Gradle,对它做了大致的了解。按照网上普遍的说法:**Gradle是以Groovy语言为基础,面向Java应用为主。基于DSL(领域特定语言)语法的自动化构建工具.** 看到这里我依旧还是有点云里雾里的,不过抓住了两个重点: 8 | > 1.Gradle是一门语言 9 | > 2.Gradle是一个自动化构建工具 10 | 既然单从概念上得不到很好的理解,那么作为学习一门语言和一个工具,只能通过使用来增强概念和功能上的了解了. 11 | 12 | ## Project和Task、Action 13 | 14 | Gradle里面的任何东西都是基于**Project**和**Task**这两个概念,基于这两个概念,Gradle官方放出的指导手册是这么描述的: 15 | 16 | * 每一个构建都是由一个或多个Project构成的.一个Project到底代表什么依赖于你想用Gradle做什么.举个例子,一个Project可以代表一个JAR或者一个网页应用.它也可能代表一个发布的 ZIP压缩包,这个ZIP可能是由许多其他项目的JARs构成的.但是一个Project不一定非要代表被构建的某个东西.它可以代表一件**要做的事,比如部署你的应用. 17 | * 每一个Project是由一个或多个Task构成的.一个Task代表一些更加细化的构建.可能是编译一些classes,创建一个JAR,生成javadoc,或者生成某个目录的压缩文件. 18 | * 每个Task又是由一个或多个Action构成的,Gradle中有两种类型的Action,分别是**doFirst**和**doLast**. 19 | 20 | 在AndroidStudio构建生成一个apk的安装包,它就要依赖于build.gradle脚本进行构建.此时**生成apk包**这样一件事情就可以理解成为一个Project(要做一件什么事),而生成apk包只是一个比较大一统的概念.打包的过程需要进行各种各样的配置,例如配置版本号,最低兼容Android几的平台,打包签名等.这些相当于**生成apk包**这个Project的一个个具体的子步骤,也就是Gradle中的Task. 21 | 22 | ## 基础语法 23 | 24 | 了解大概的一些基本概念之后,最重要的还是开始下手打码实战,创建自己的第一个Gradle构建脚本文件build.gradle 25 | 26 | ```groovy 27 | task hello { 28 | doLast { 29 | println 'Hello world!' 30 | } 31 | } 32 | ``` 33 | 34 | 在命令行里,进入脚本所在的文件夹然后输入命令**gradle -q hello**来执行构建脚本(前提是你安装了Gradle并配置了环境变量),会在控制台窗口得到如下输出 35 | 36 | ``` 37 | $ gradle -q hello 38 | Hello world! 39 | ``` 40 | 这个命令所执行的事情可以分为以下几个步骤 41 | 1.去build.gradle文件中查找hello这个task,并且做编译执行; 42 | 2.执行hello task中每个action里面的流程,此处只有doLast{}一个action负责输出Hello world; 43 | 44 | 接下来看另外一段Gradle脚本 45 | 46 | ```groovy 47 | task upper << { 48 | String someString = 'mY_nAmE' 49 | println "Original: " + someString 50 | println "Upper case: " + someString.toUpperCase() 51 | } 52 | ``` 53 | 54 | 执行**gradle -q upper**运行后,可以看到控制台窗口的输出如下: 55 | 56 | ``` 57 | $ gradle -q upper 58 | Original: mY_nAmE 59 | Upper case: MY_NAME 60 | ``` 61 | 62 | 看到此处的代码,需要做一个简单的解释一下,上面的这段代码和下面的这种写法是等价的,上面的写法其实是Gradle提供的doLast{}的一种简写方式,因为Gradle直接重载了`<<`符号. 63 | 64 | ```groovy 65 | task upper { 66 | doLast{ 67 | String someString = 'mY_nAmE' 68 | println "Original: " + someString 69 | println "Upper case: " + someString.toUpperCase() 70 | } 71 | } 72 | ``` 73 | 看到这里,有没有发现其实Gradle的语法,其实跟Java是非常类似的,哈哈...其实网上也存在着一种说法:Groovy就是没有类型的Java,为什么说是Groovy,其实Gradle相当于Groovy的子类,Groovy的所有特性都被Gradle完整继承了.看完下面的代码就能理解为何成为没有类型的Java的原因了. 74 | 75 | ```groovy 76 | task notype << { 77 | def oneInt = 1 //等价于 int oneInt = 1 78 | def oneFloat = 1.00 //等价于 ioneFloat = 1.00 79 | def oneString = 'Clock'//等价于 oneString = 'Clock' 80 | 81 | println "oneInt: " + oneInt 82 | println "oneFloat: " + oneFloat 83 | println "oneString: " + oneString 84 | } 85 | ``` 86 | 87 | 编译运行以上代码后,即可以看到以下输出 88 | 89 | ``` 90 | $ gradle -q notype 91 | oneInt: 1 92 | oneFloat: 1.00 93 | oneString: Clock 94 | ``` 95 | 96 | 之所以说Groovy是无类型的Java,就是因为不管所有的类型都可以使用**def(define)**来定义一个变量,Gradle会根据你赋值的类型,将变量转换成对应的基本类型. 97 | 最后来看一下Gradle里面如何使用循环的,直接看下面两段代码 98 | 99 | ```groovy 100 | task rounder << { 101 | 10.times{ 102 | println "it is: " + it 103 | } 104 | } 105 | ``` 106 | 107 | ```groovy 108 | task rounder << { 109 | 10.times{a-> 110 | println "it is: " + a 111 | } 112 | } 113 | ``` 114 | 上面的两段代码的执行结果相同,如下: 115 | ``` 116 | $ gradle -q rounder 117 | it is: 0 118 | it is: 1 119 | it is: 2 120 | it is: 3 121 | it is: 4 122 | it is: 5 123 | it is: 6 124 | it is: 7 125 | it is: 8 126 | it is: 9 127 | ``` 128 | 都是做一个10次的循环,**.times** 和 **it**是关键字,其中**..times**.表示循环,**10.times**表示执行10次的一个循环,**it**表示循环中的计数值. 对于**it**,我们也可以自定义一个变量获取这个计数值,像第二段代码中的**a->**就是表示用**a**来取代**it**获取这个循环中的计数值.对于 129 | ``` 130 | println "it is: " + a 131 | 132 | ``` 133 | 我们也可以等价写成 134 | ``` 135 | println "it is: $a"//$变量名,表示去取变量的值 136 | 137 | ``` 138 | 139 | ## 任务依赖 140 | 141 | Gradle中存在一种依赖关系,所谓依赖关系可以简单的描述成一个Task的执行需要已另一个Task作为基础,继续看下面的两段代码 142 | 143 | ```groovy 144 | task hello << { 145 | println 'Hello world!' 146 | } 147 | task intro(dependsOn: hello) << { 148 | println "I'm Gradle" 149 | } 150 | ``` 151 | 152 | ```groovy 153 | task intro(dependsOn: 'hello') << { 154 | println "I'm Gradle" 155 | } 156 | task hello << { 157 | println 'Hello world!' 158 | } 159 | ``` 160 | 161 | 上面两段代码的都是表示在执行intro task之前会先依赖执行hello task,**唯一的区别就是被依赖的task是定义在调用之前还是调用之后**,看到这里是否感觉这种依赖的关系相当于函数调用传入参数那样..显得非常易懂. 162 | 163 | ## 多项目和远程仓库 164 | 165 | Gradle支持可以将一个Project划分成为一个或多个子Project来构成 166 | 167 | ``` 168 | include 'SubProject1','SubProject2','SubProject3'.........; 169 | ``` 170 | 可以支持使用本地的mavenCentral库,或者是远程服务器上的库 171 | ```groovy 172 | repositories { 173 | mavenCentral()//本地库支持 174 | maven { 175 | url "http://repo.mycompany.com/maven2" //远程库地址 176 | } 177 | 178 | } 179 | ``` 180 | 181 | ## 常用的Gradle命令 182 | 183 | 下面介绍一些Gradle中常用的命令操作 184 | * 查看版本号: **gradle -v** 185 | * 编译执行某个task: **gradle Task名** 186 | * 静默编译执行某个task: **gradle -q Task名**(q表示quiet模式,表示编译执行Gradle脚本的过程中,只输出必要的信息. 除了quiet模式外,Gradle中还有其他三种模式) 187 | * 编译执行某个Project中的某个task:**gradle -b Project名 Task名**(Gradle默认只执行build.gradle文件中,自定义其他文件xxx.gradle编译运行显式指定Project名称,这里的build.gradle其实表示的就是build Project) 188 | * 显示所有的Project:**gradle projects** 189 | * 显示所有的task:**gradle tasks** 190 | * 显示gradle的gui:**gradle --gui** 或 **gradle --gui&**(后台运行) 191 | * 查找所有的gradle命令: **gradle --help** 192 | 193 | ##最后 194 | 195 | 此处只是一小部分gradle的基础使用总结,更多的gradle使用方式请戳这里[Gradle User Guide](https://docs.gradle.org/current/userguide/userguide.html) -------------------------------------------------------------------------------- /Android/Gradle/3_ProGuard基础语法和打包配置.md: -------------------------------------------------------------------------------- 1 | # ProGuard基础语法和打包配置 2 | 3 | 这是对Android打包混淆所需配置所做的总结. 4 | 5 | ## ProGuard常用语法 6 | 7 | 下面列出一些常用的语法 8 | 9 | * -libraryjars class_path 应用的依赖包,如android-support-v4 10 | * -keep [,modifier,...] class_specification 不混淆某些类 11 | * -keepclassmembers [,modifier,...] class_specification 不混淆类的成员 12 | * -keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员 13 | * -keepnames class_specification 不混淆类及其成员名 14 | * -keepclassmembernames class_specification 不混淆类的成员名 15 | * -keepclasseswithmembernames class_specification 不混淆类及其成员名 16 | * -assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等 17 | * -dontwarn [class_filter] 不提示warnning 18 | 19 | 更多关于ProGuard混淆规则和语法,直接上[ProGuard官网](http://proguard.sourceforge.net/index.html#manual/usage.html) 20 | 21 | ## Android的混淆原则 22 | 23 | Android混淆打包混淆的原则如下 24 | * 反射用到的类不混淆 25 | * JNI方法不混淆 26 | * AndroidMainfest中的类不混淆,四大组件和Application的子类和Framework层下所有的类默认不会进行混淆 27 | * Parcelable的子类和Creator静态成员变量不混淆,否则会产生android.os.BadParcelableException异常 28 | * 使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象 29 | * 使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则 30 | * 有用到WEBView的JS调用也需要保证写的接口方法不混淆 31 | 32 | ## 常用的混淆配置和解析 33 | 34 | 先看看下面Google默认配置的混淆文件,文件的位置: 35 | > `AndroidStudio的安装目录\sdk\tools\proguard\proguard-android.txt` 36 | 37 | ``` 38 | # This is a configuration file for ProGuard. 39 | # http://proguard.sourceforge.net/index.html#manual/usage.html 40 | 41 | -dontusemixedcaseclassnames 42 | -dontskipnonpubliclibraryclasses 43 | -verbose 44 | 45 | # Optimization is turned off by default. Dex does not like code run 46 | # through the ProGuard optimize and preverify steps (and performs some 47 | # of these optimizations on its own). 48 | -dontoptimize 49 | -dontpreverify 50 | # Note that if you want to enable optimization, you cannot just 51 | # include optimization flags in your own project configuration file; 52 | # instead you will need to point to the 53 | # "proguard-android-optimize.txt" file instead of this one from your 54 | # project.properties file. 55 | 56 | -keepattributes *Annotation*//使用注解需要添加 57 | -keep public class com.google.vending.licensing.ILicensingService 58 | -keep public class com.android.vending.licensing.ILicensingService 59 | 60 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 61 | -keepclasseswithmembernames class * {//指定不混淆所有的JNI方法 62 | native ; 63 | } 64 | 65 | # keep setters in Views so that animations can still work. 66 | # see http://proguard.sourceforge.net/manual/examples.html#beans 67 | -keepclassmembers public class * extends android.view.View {//所有View的子类及其子类的get、set方法都不进行混淆 68 | void set*(***); 69 | *** get*(); 70 | } 71 | 72 | # We want to keep methods in Activity that could be used in the XML attribute onClick 73 | -keepclassmembers class * extends android.app.Activity {//不混淆Activity中参数类型为View的所有方法 74 | public void *(android.view.View); 75 | } 76 | 77 | # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 78 | -keepclassmembers enum * {//不混淆Enum类型的指定方法 79 | public static **[] values(); 80 | public static ** valueOf(java.lang.String); 81 | } 82 | //不混淆Parcelable和它的子类,还有Creator成员变量 83 | -keep class * implements android.os.Parcelable { 84 | public static final android.os.Parcelable$Creator *; 85 | } 86 | //不混淆R类里及其所有内部static类中的所有static变量字段 87 | -keepclassmembers class **.R$* { 88 | public static ; 89 | } 90 | 91 | # The support library contains references to newer platform versions. 92 | # Don't warn about those in case this app is linking against an older 93 | # platform version. We know about them, and they are safe. 94 | -dontwarn android.support.**//不提示兼容库的错误警告 95 | 96 | 97 | ``` 98 | Google为我们提供好的混淆代码如上,但是往往我们还需要添加自己的混淆规则,这是因为我们可能会遇到以下几种情况: 99 | * 代码中使用了反射,如一些ORM框架的使用 100 | * 使用GSON、fastjson等JSON解析框架所生成的对象类 101 | * 继承了Serializable接口的类 102 | * 引用了第三方开源框架或继承第三方SDK,如开源的okhttp网络访问框架,百度定位SDK等 103 | * 有用到WEBView的JS调用接口 104 | 105 | 针对以上几种情况,分别给出下列对应解决的混淆规则 106 | >1.代码中使用了反射,加入下面的混淆规则即可. 107 | 108 | ``` 109 | -keepattributes Signature 110 | -keepattributes EnclosingMethod 111 | ``` 112 | >2.使用GSON、fastjson等JSON解析框架所生成的对象类,加入下面的混淆规则即可.假设com.clock.bean包下所有的类都是JSON解析生成对象的类 113 | 114 | ``` 115 | -keep class com.clock.bean.**{*;}//不混淆所有的com.clock.bean包下的类和这些类的所有成员变量 116 | 117 | ``` 118 | >3.继承了Serializable接口的类,加上如下规则 119 | 120 | ``` 121 | //不混淆Serializable接口的子类中指定的某些成员变量和方法 122 | -keepclassmembers class * implements java.io.Serializable { 123 | static final long serialVersionUID; 124 | private static final java.io.ObjectStreamField[] serialPersistentFields; 125 | private void writeObject(java.io.ObjectOutputStream); 126 | private void readObject(java.io.ObjectInputStream); 127 | java.lang.Object writeReplace(); 128 | java.lang.Object readResolve(); 129 | } 130 | ``` 131 | >4.引用了第三方开源框架或继承第三方SDK情况比较复杂,开发过程中使用了知名成熟的开发框架都会有给出它的混淆规则,第三方的SDK也一样。这里以okhttp框架和百度地图sdk为例 132 | 133 | ``` 134 | //okhttp框架的混淆 135 | -dontwarn com.squareup.okhttp.internal.http.* 136 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 137 | -keepnames class com.levelup.http.okhttp.** { *; } 138 | -keepnames interface com.levelup.http.okhttp.** { *; } 139 | -keepnames class com.squareup.okhttp.** { *; } 140 | -keepnames interface com.squareup.okhttp.** { *; } 141 | 142 | //百度sdk的混淆 143 | -keep class com.baidu.** {*;} 144 | -keep class vi.com.** {*;} 145 | -dontwarn com.baidu.** 146 | 147 | ``` 148 | >5.有用到WEBView的JS调用接口,需加入如下规则 149 | 150 | ``` 151 | -keepclassmembers class fqcn.of.javascript.interface.for.webview { 152 | public *; 153 | } 154 | -keep class com.xxx.xxx.** { *; }//保持WEB接口不被混淆 此处xxx.xxx是自己接口的包名 155 | ``` 156 | 157 | ## ProGuard语法的延伸 158 | 下面对ProGuard语法做一些小小的延伸和拓展 159 | 160 | * 不混淆某个类 161 | 162 | ``` 163 | -keep class com.clock.**//不混淆所有com.clock包下的类,** 换成具体的类名则表示不混淆某个具体的类 164 | 165 | ``` 166 | * 不混淆某个类和成员变量 167 | 168 | ``` 169 | -keep class com.clock.**{*;}//不混淆所有com.clock包下的类和类中的所有成员变量,**可以换成具体类名,*可以换成具体的字段,可参照Serialzable的混淆 170 | 171 | ``` 172 | * 不混淆类中的方法或变量,参照AndroidStudio给的默认混淆文件的书写方式 173 | 174 | * 使用`assumenosideeffects`移除代码 175 | 176 | ``` 177 | //移除Log类打印各个等级日志的代码,打正式包的时候可以做为禁log使用,这里可以作为禁止log打印的功能使用,另外的一种实现方案是通过BuildConfig.DEBUG的变量来控制 178 | -assumenosideeffects class android.util.Log { 179 | public static *** v(...); 180 | public static *** i(...); 181 | public static *** d(...); 182 | public static *** w(...); 183 | public static *** e(...); 184 | } 185 | ``` 186 | ## 总结 187 | 188 | 大致的做了ProGuard的使用总结,光看不写是不会有好代码出来的,动手打码吧,感谢相关参考资料的作者。 -------------------------------------------------------------------------------- /Android/Gradle/4_AndroidStudio下ProGuard混淆打包.md: -------------------------------------------------------------------------------- 1 | # AndroidStudio下ProGuard混淆打包 2 | 3 | 继前一篇笔记[ProGuard基础语法和打包配置](3_ProGuard基础语法和打包配置.md)总结了一些打包混淆需要注意的地方。这几天忙着新项目的上线,切换到AndroidStudio下开发后,需要写一下gradle的打包脚本,因为是新项目,也需要重新写一下混淆配置文件。结果碰到了下面一个问题**混淆打包的时候移除打log的代码的配置不成功**。前一篇笔记说过,打包的时候做了如下的配置就可以移除工程里面的log,避免打包发布后的一些问题. 4 | 5 | ```proguard 6 | -assumenosideeffects class android.util.Log{ 7 | public static int v(...); 8 | public static int i(...); 9 | public static int d(...); 10 | public static int w(...); 11 | public static int e(...); 12 | } 13 | 14 | -assumenosideeffects class java.io.PrintStream{ 15 | public void println(%); 16 | public void println(**); 17 | } 18 | ``` 19 | 20 | 结果在自定义的混淆文件下,捣腾了很久发现一点效果都木有,郁闷了很久,莫非**ProGuard的这些处理已经失效了?**脑子里满是大问号,Google了很久也没有发现什么线索,索性就先丢了一边。但是作为一个强迫症程序员,过几天又想起了这个问题,有空便索性研究琢磨一下,还真的找到问题的所在,顺利的解决了。 21 | 22 | ## 问题出在哪? 23 | 24 | 思前想后,发现Google了很久都没有所以然,有溜达去ProGuard的官网看了一下语法,也没有提及废弃到上面那种优化方式。那么,基本可以断定是我自己的配置出了问题。但我仔细检查了自己的配置,发现并无异样,网上提及到的这种优化方式的失效的情况,也只有在混淆文件配置了 25 | 26 | * -dontoptimize(顾名思义,don't optimize 不优化) 27 | 28 | 的时候才回导致失效,可是问题我压根自己的配置文件并没有配这个啊啊啊啊啊啊啊!额,脑子一转,不对,我用gradle来打包的,AndroidStudio生成build.gradle打包文件的时候,就指定了一个默认的的混淆文件**proguard-android.txt**(在 SDK目录/tools/proguard/ 目录下面)另外一个让我们自行添加混淆规则的**proguard-rules.pro**文件就在我们写代码的moudle目录下面。 29 | 30 | ```groovy 31 | buildTypes { 32 | release { 33 | minifyEnabled true 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | ``` 38 | 39 | 如此一来,自己写的**proguard-rules.pro**里面没问题,那么基本是在**proguard-android.txt**里面出了问题,索性直接打开那个文件看看,果不其然,看到了下面的两行混淆配置 40 | 41 | ```proguard 42 | -dontoptimize 43 | -dontpreverify 44 | ``` 45 | 46 | 这样就能明白自己去除log的代码失效的原因了。哈哈,找到罪魁祸首后,直接把这个配置去掉就ok了,鸡冻得赶紧重新打包享受胜利的果实。结果打包到了一半,妈蛋,直接报错终止了。 47 | 48 | ## 去了-dontoptimize还不行 49 | 50 | 额,开了好久,发现被打回原点。no,还达不到原点,连打包都打不了。是不是还要什么地方需要改动呢,后来当天没想到什么好方法,索性隔了一天再回来捣腾,又发现了一些问题,在sdk自带的配置混淆文件的目录下,有着三个混淆的配置文件 51 | 52 | * proguard-android.txt 53 | * proguard-android-optimize.txt 54 | * proguard-project.txt 55 | 56 | 打开之前的**proguard-android.txt**看到了下面这段注释 57 | 58 | ``` 59 | -dontoptimize 60 | -dontpreverify 61 | # Note that if you want to enable optimization, you cannot just 62 | # include optimization flags in your own project configuration file; 63 | # instead you will need to point to the 64 | # "proguard-android-optimize.txt" file instead of this one from your 65 | # project.properties file. 66 | ``` 67 | 68 | 哈哈,这回真是如梦初醒啊啊啊啊啊啊!,赶紧把gradle里面的系统混淆配置文件改成**proguard-android-optimize.txt**,再搭上自己写的那份混淆文件一起打包,过了一会搞定,终于打出一个我想要的混淆包出来了 69 | 70 | ## 总结 71 | 72 | 仔细的去看了一下**proguard-android.txt**和**proguard-android-optimize.txt**的区别,其实主要的问题是出现在了少了下面的这段配置 73 | 74 | ``` 75 | -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* 76 | -optimizationpasses 5 77 | -allowaccessmodification 78 | -dontpreverify 79 | 80 | # The remainder of this file is identical to the non-optimized version 81 | # of the Proguard configuration file (except that the other file has 82 | # flags to turn off optimization). 83 | 84 | -dontusemixedcaseclassnames 85 | -dontskipnonpubliclibraryclasses 86 | -verbose 87 | ``` 88 | 89 | 打包加入优化需要指定优化等级和优化策略算法的一些配置等等,因为去了-dontoptimize后没有配置上面这些,所导致连包都打不了了。 90 | 91 | 另外,**instead you will need to point to the "proguard-android-optimize.txt" file instead of this one from your project.properties file.**这提示其实是旧的开发工具ADT下面的提示而已,因为ADT下混淆配置是在**project.properties**指定。换成AndroidStudio开发的话,去build.gradle的构建脚本中配置就好了,如下 92 | 93 | ```groovy 94 | buildTypes { 95 | release { 96 | minifyEnabled true 97 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 98 | } 99 | } 100 | ``` 101 | 102 | 啰里吧嗦又一篇,与君分享,不喜勿喷。。哈哈 -------------------------------------------------------------------------------- /Android/Gradle/5_Gradle多渠道和自动化打包(基础篇).md: -------------------------------------------------------------------------------- 1 | # Gradle多渠道自动化打包(基础篇) 2 | 3 | 最近由于忙着公司项目上的开发和调整,一直没有多少时间停下来做笔记。今天继续记录一下AndroidStudio下如何使用Gradle打包的一些基本操作,同样希望能够帮到一些需要这些资源的开发者。代码上的编写非常简单,主要分为以下2步走即可 4 | 5 | > **1.配置渠道;** 6 | > 7 | > **2.配置渠道关键信息(如:设置渠道名,渠道ID);** 8 | 9 | ## 配置渠道 10 | 11 | 说到配置渠道,本身来说非常简单,我们直接打开AndroidStudio为我们module生成的build.gradle构建脚本。在android的闭包里面添加productFlavors的闭包,并配置上我们所要打包的渠道 12 | 13 | ```groovy 14 | android { 15 | ... 16 | productFlavors { 17 | wandoujia {} 18 | qihu360 {} 19 | baidu {} 20 | } 21 | } 22 | ``` 23 | 24 | 这里我添加了豌豆荚、360和百度手机助手作为我们app的渠道,到这里我们已经完成了第一步的配置。有木有so easy的赶脚。 25 | 26 | ## 配置渠道关键信息 27 | 28 | 接下来需要配置一些渠道关键信息,所谓的关键信息就是我们给渠道定义的**渠道号**(说白了就是对app分发渠道的一个标识,不懂的孩纸就需要自行上网搜索了)。渠道统计里面最经常使用的估计是非友盟莫属了。这里我们也以友盟作为例子 29 | 30 | ```xml 31 | 34 | ``` 35 | 36 | 用过友盟的朋友都知道,我们需要在app的androidManifest.xml文件里面去配置这样一个渠道信息。以便友盟进行区别分析和统计。在平常开发过程中我们通常会写死在xml配置里面。而此时如果涉及到多渠道打包,我们就不能这么操作了。这里我们做一点小小的变化,把上面的值**origin**抽取到如下名为**CHANNEL_VALUE**的变量中 37 | 38 | ```xml 39 | 42 | ``` 43 | 44 | 到此,AndroidMainfest里面的活干完了,我们重新build.gradle的构建脚本里面去。在刚刚指定的渠道下面添加下面这样一段循环 45 | 46 | ```groovy 47 | android { 48 | ... 49 | productFlavors { 50 | ... 51 | } 52 | productFlavors.all { flavor -> 53 | flavor.manifestPlaceholders = [CHANNEL_VALUE: name] 54 | } 55 | } 56 | ``` 57 | 58 | 为我们生成每个渠道包的AndroidManifest里面的变量**CHANNEL_VALUE**赋值。到此,我们就能顺利的用友盟对我们的渠道包进行区别统计了。 59 | 60 | ## 打包 61 | 62 | 完成了上面的配置之后,我们就可以在AndroidStudio进行批量的打包了。 63 | 64 | 1.点击生成签名包 65 | 66 | ![点击生成签名包](http://c.hiphotos.baidu.com/image/pic/item/8b82b9014a90f603e122c4473f12b31bb051ed24.jpg) 67 | 68 | 2.勾选要打包的moudle 69 | 70 | ![勾选要打包的moudle](http://b.hiphotos.baidu.com/image/pic/item/5243fbf2b21193134174a4b063380cd791238dff.jpg) 71 | 72 | 3.选择打包的数字签名(如果没有就自己点击create new...创建一个) 73 | 74 | ![选择打包的数字签名](http://f.hiphotos.baidu.com/image/pic/item/91529822720e0cf31a6516fb0c46f21fbe09aa24.jpg) 75 | 76 | 4.选择好生成包的路径和渠道包名(可以看到我们配置好的渠道都在里面) 77 | 78 | ![选择好生成包的路径和渠道包名](http://d.hiphotos.baidu.com/image/pic/item/d31b0ef41bd5ad6ebe233cea87cb39dbb7fd3cd3.jpg) 79 | 80 | 5.点击finish静静的等待生成渠道包就可以了。 81 | 82 | ![生成渠道包](http://b.hiphotos.baidu.com/image/pic/item/a50f4bfbfbedab64823815c0f136afc379311e63.jpg) 83 | 84 | ## 验证 85 | 86 | 为了更好的看到打包是否生效,我直接拿了生成的baidu渠道包**app-baidu-release.apk**来做一个反编译(对反编译工具有兴趣的朋友请戳这里[Android反编译工具系列](/Tools/Android反编译工具系列.md))的验证 87 | 88 | >反编译xml文件 89 | 90 | ![反编译xml文件](http://d.hiphotos.baidu.com/image/pic/item/3812b31bb051f81915df444adcb44aed2e73e73c.jpg) 91 | 92 | >反编译成功得到的文件 93 | > 94 | ![反编译成功得到的文件](http://b.hiphotos.baidu.com/image/pic/item/9f2f070828381f30487fcba9af014c086e06f048.jpg) 95 | 96 | >打开AndroidMainfest验证结果 97 | 98 | ![打开AndroidMainfest验证结果](http://b.hiphotos.baidu.com/image/pic/item/6a63f6246b600c33568399c81c4c510fd9f9a13c.jpg) 99 | 100 | 经过反编译后,最终可以确定多渠道打包成功。如果想知道更多gradle自动化多渠道打包的知识,欢迎继续阅读下一篇笔记[Gradle多渠道和自动化打包(深入篇)](6_Gradle多渠道和自动化打包(深入篇).md) 101 | 102 | 最后,献上完整的基础打包代码 103 | 104 | ```groovy 105 | apply plugin: 'com.android.application' 106 | 107 | android { 108 | compileSdkVersion 21 109 | buildToolsVersion "21.1.2" 110 | 111 | defaultConfig { 112 | applicationId "com.clock.gradle" 113 | minSdkVersion 14 114 | targetSdkVersion 21 115 | versionCode 1 116 | versionName "1.0" 117 | } 118 | buildTypes { 119 | release { 120 | minifyEnabled false 121 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 122 | } 123 | } 124 | 125 | productFlavors { 126 | wandoujia {} 127 | qihu360 {} 128 | baidu {} 129 | } 130 | 131 | productFlavors.all { flavor -> 132 | flavor.manifestPlaceholders = [CHANNEL_VALUE: name] 133 | } 134 | 135 | } 136 | 137 | dependencies { 138 | compile fileTree(dir: 'libs', include: ['*.jar']) 139 | compile 'com.android.support:appcompat-v7:21.0.3' 140 | } 141 | 142 | ``` -------------------------------------------------------------------------------- /Android/Gradle/6_Gradle多渠道和自动化打包(深入篇).md: -------------------------------------------------------------------------------- 1 | # Gradle多渠道和自动化打包(深入篇) 2 | 3 | 继[Gradle多渠道和自动化打包(基础篇)](5_Gradle多渠道和自动化打包(基础篇).md)后,接着记录一下多渠道自动化打包的另外一些配置操作,主要分为以下5个方面 4 | 5 | > **1.一个渠道多个信息** 6 | 7 | > **2.打包签名配置** 8 | 9 | > **3.修改生成apk包名** 10 | 11 | > **4.设置编译时的渠道信息** 12 | 13 | > **5.其他** 14 | 15 | 16 | ## 添加多个渠道信息 17 | 18 | 上一面文章里面给出是示例,只是简单的给**UMENG_CHANNEL**打上不同的渠道名。那么,如果我想要为每个渠道名添加一个对于的渠道ID,那应该怎么做咧?首先,我在原先生成友盟渠道名的meta-data那里创建一个新的meta-data,作为标识每个渠道的ID。 19 | 20 | ```xml 21 | 24 | 25 | 28 | 29 | ``` 30 | 31 | 按照我的想法,豌豆荚,360手机助手和百度手机助手的渠道id分别设置成200、201、202。于是,移出原先的循环,只能直接去到各个渠道的闭包下做配置。 32 | 33 | ```groovy 34 | 35 | android { 36 | ... 37 | 38 | productFlavors { 39 | wandoujia { 40 | manifestPlaceholders = [CHANNEL_VALUE: 'wandoujia' , CHANNEL_ID:200] 41 | } 42 | qihu360 { 43 | manifestPlaceholders = [CHANNEL_VALUE: '360' , CHANNEL_ID:201] 44 | } 45 | baidu { 46 | manifestPlaceholders = [CHANNEL_VALUE: 'baidu' , CHANNEL_ID:202] 47 | } 48 | } 49 | 50 | } 51 | 52 | ``` 53 | 54 | 到这里就可以在打包的时候成功打上渠道名和其对应的ID号了。如果想要验证结果的话,还是可以去反编译查看一下。 55 | 56 | ## 打包签名配置 57 | 58 | 打包签名的配置分为两种情况,一种是采用AndroidStudio来打包,这样只需要在步骤中勾选好打包的签名文件已经填写相关的密码信息,即可完成;另外一种,是进入到命令行界面进行打包操作,这时候就需要我们在build.gradle脚本中做好如下的签名信息配置 59 | 60 | ```groovy 61 | 62 | android { 63 | ... 64 | 65 | signingConfigs { 66 | debug { 67 | 68 | } 69 | release { 70 | storeFile '打包签名路径' 71 | storePassword 'XXX' 72 | keyAlias 'XXX' 73 | keyPassword 'XXX' 74 | } 75 | } 76 | 77 | } 78 | 79 | ``` 80 | 81 | 但这种做法是**非常不建议**的,因为这样会导致我们签名信息泄露,且不方便于我们进行控制和管理。所以,官方提倡的做法是,把这些关键信息存放到文件中去,然后再gradle打包脚本中读取信息。所以,我直接在当前的module下面创建了一个**signing.properties**的配置文件, 82 | 83 | ![创建配置文件](http://e.hiphotos.baidu.com/image/pic/item/e850352ac65c103897436cc3b4119313b07e89f6.jpg) 84 | 85 | 在这里面通过键值对的方式写好签名的关键信息 86 | 87 | ![填写签名信息](http://a.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd595404af557da81cb39db3d9b.jpg) 88 | 89 | 再根据下面的gradle打包代码,从这份文件中读取签名信息出来打包 90 | 91 | ```groovy 92 | 93 | android { 94 | ... 95 | 96 | signingConfigs { 97 | debug { 98 | 99 | } 100 | release { 101 | storeFile 102 | storePassword 103 | keyAlias 104 | keyPassword 105 | } 106 | } 107 | 108 | buildTypes { 109 | release { 110 | signingConfig signingConfigs.release //设置签名信息 111 | } 112 | } 113 | 114 | } 115 | 116 | //读取文件中的信息来配置打包签名 117 | File propFile = file('signing.properties'); 118 | if (propFile.exists()) { 119 | def Properties props = new Properties() 120 | props.load(new FileInputStream(propFile)) 121 | if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') && 122 | props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) { 123 | android.signingConfigs.release.storeFile = file(props['STORE_FILE']) 124 | android.signingConfigs.release.storePassword = props['STORE_PASSWORD'] 125 | android.signingConfigs.release.keyAlias = props['KEY_ALIAS'] 126 | android.signingConfigs.release.keyPassword = props['KEY_PASSWORD'] 127 | } else { 128 | android.buildTypes.release.signingConfig = null 129 | } 130 | } else { 131 | android.buildTypes.release.signingConfig = null 132 | } 133 | 134 | .... 135 | 136 | ``` 137 | 138 | TeamLeader可以在提交代码的时候把**signing.properties**文件忽略掉,这样就不会将签名等信息泄露出去,对app的安全造成威胁。同时,也方便TeamLeader进行控制管理。 139 | 140 | ## 修改生成apk包名 141 | 142 | 在使用AndroidStudio打渠道包的时候,生成的渠道包默认都是以**app名-渠道名-release.apk**的格式命名。如果你想在让生成的渠道包进行自定义的格式命名,那么可以在gradle脚本中这样做 143 | 144 | ```groovy 145 | 146 | apply plugin: 'com.android.application' 147 | 148 | //获取产品的名字 149 | def getProductName() { 150 | return "clock" 151 | } 152 | //获取当前系统的时间 153 | def releaseTime() { 154 | return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC")) 155 | } 156 | 157 | android { 158 | ... 159 | 160 | signingConfigs { 161 | ... 162 | } 163 | 164 | buildTypes { 165 | ... 166 | } 167 | //修改生成的apk名字,格式为 app名_版本号_打包时间_渠道名_release.apk 168 | applicationVariants.all { variant -> 169 | variant.outputs.each { output -> 170 | def oldFile = output.outputFile 171 | if (variant.buildType.name.equals('release')) { 172 | def releaseApkName = getProductName() + "_v${defaultConfig.versionName}_${releaseTime()}_" + variant.productFlavors[0].name + '_release.apk' 173 | output.outputFile = new File(oldFile.parent, releaseApkName) 174 | } 175 | } 176 | } 177 | 178 | } 179 | .... 180 | 181 | ``` 182 | 183 | 按照上面的代码进行打包之后,生成的包名就会变成我们重新指定的格式。这样肯定比我们手工操作方便多了,码农的任务就是要用代码解放双手,哈哈。 184 | 185 | ## 设置编译时的渠道信息 186 | 187 | 在我们配置好打发布包的脚本时,随之也会遇到一个问题。就是,我们再AndroidManifest里面做的配置 188 | 189 | ![AndroidManifest配置](http://a.hiphotos.baidu.com/image/pic/item/0e2442a7d933c89599d4317ad71373f08202000c.jpg) 190 | 191 | 在平常的开发调试模式下,这两个值它会变成什么值呢?是不是突然有点懵了...别懵,这时候你只要来到androidStudio的左下角点开**Build Variants**窗口 192 | 193 | ![Build Variants](http://c.hiphotos.baidu.com/image/pic/item/aa64034f78f0f736fd46e6000c55b319ebc41372.jpg) 194 | 195 | 点击下拉,就可以勾选我们开发模式下要生成什么渠道信息了。 196 | 197 | ![选择调试模式渠道](http://a.hiphotos.baidu.com/image/pic/item/622762d0f703918f28ada8cb573d269759eec4b7.jpg) 198 | 199 | 如果你的开发工具左下角没有**Build Variants**窗口,那自己去到**工具栏>View>Tool Windows**里面打开。 200 | 201 | ## 其他 202 | 203 | 除了以上的一些配置外,在打包的时候还有另外一些配置问题,如:配置混淆规则,配置混淆优化,移除无用的资源文件,压缩对齐apk包,突破65535个方法限制等等。这里主要记录一下最后的65535方法限制的问题,其他的会在最后给出完整的打包脚本。 204 | 205 | Android生成的app的apk包要求所有方法的总数必须小于65536个方法,否则就无法生成单个class.dex文件(干过反编译这事的人应该都熟悉这东东)。所以,一个app在不断发展迭代的过程之后,必然会面临这个问题。gradle给出的解决方法很简单 206 | 207 | 208 | ```groovy 209 | 210 | android { 211 | ... 212 | buildTypes { 213 | release { 214 | ... 215 | multiDexEnabled true//启用生成个dex文件的支持 216 | } 217 | } 218 | 219 | 220 | dependencies { 221 | compile fileTree(dir: 'libs', include: '*.jar') 222 | compile files('libs/locSDK_5.01.jar') 223 | compile 'com.umeng.analytics:analytics:latest.integration' 224 | //添加支持multidex的兼容包 225 | compile 'com.android.support:multidex:1.0.0' 226 | } 227 | 228 | ``` 229 | 230 | 除此之外,我们还需要继承MultiDexApplication,并重写attachBaseContext方法 231 | 232 | ```java 233 | 234 | /** 235 | * 处理解决mutiDex的问题 236 | * 237 | * Created by Clock on 2015/7/23. 238 | */ 239 | public class BaseApplication extends MultiDexApplication{ 240 | 241 | @Override 242 | protected void attachBaseContext(Context base) { 243 | super.attachBaseContext(base); 244 | //支持多dex的apk安装 245 | MultiDex.install(this); 246 | } 247 | } 248 | 249 | ``` 250 | 251 | 这样就可以解决问题了,不过因为Android系统的各种原因,这种方式只能够在Android4.0开始及之后的平台生效。因为在Multidex在2.x的系统上因为突然需要开辟一大块内存,所以会造成崩溃而无法使用的问题。 252 | 253 | 254 | ## 最后 255 | 256 | 好了,本次的笔记就到此了。记录能够帮助自己消化知识,同时也分享给其他需要的开发者。最后献上一份完整的build.gradle打包脚本,还有一张打包生成apk的整个流程图。 257 | 258 | ```groovy 259 | apply plugin: 'com.android.application' 260 | 261 | //获取生成的产品名 262 | def getProductName() { 263 | return "clock" 264 | } 265 | 266 | //获取打包的时间 267 | def releaseTime() { 268 | return new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC")) 269 | } 270 | 271 | 272 | android { 273 | compileSdkVersion 21 274 | buildToolsVersion "21.1.2" 275 | 276 | packagingOptions { 277 | exclude 'META-INF/LICENSE.txt' 278 | exclude 'META-INF/NOTICE.txt' 279 | exclude 'META-INF/MANIFEST.MF' 280 | } 281 | 282 | lintOptions { 283 | //忽略一些构建信息,降低对错误的检查 284 | checkReleaseBuilds false 285 | abortOnError false 286 | } 287 | 288 | defaultConfig { 289 | applicationId "com.clock.chatlink" 290 | minSdkVersion 9 291 | targetSdkVersion 21 292 | versionCode 1 293 | versionName "1.0" 294 | } 295 | 296 | signingConfigs { 297 | debug { 298 | 299 | } 300 | //配置签名的关键信息 301 | release { 302 | storeFile 303 | storePassword 304 | keyAlias 305 | keyPassword 306 | } 307 | } 308 | 309 | buildTypes { 310 | release { 311 | //启用混淆代码的功能 312 | minifyEnabled true 313 | //压缩对齐生成的apk包 314 | zipAlignEnabled true 315 | //指定混淆规则,需要压缩优化的混淆要把proguard-android.txt换成proguard-android.txt 316 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 317 | //指定打release包的签名 318 | signingConfig signingConfigs.release 319 | //移除无用的资源文件 320 | shrinkResources true 321 | //启用multidex的支持 322 | multiDexEnabled true 323 | } 324 | } 325 | 326 | productFlavors { 327 | wandoujia { 328 | manifestPlaceholders = [CHANNEL_VALUE: 'wandoujia' , CHANNEL_ID:200] 329 | } 330 | qihu360 { 331 | manifestPlaceholders = [CHANNEL_VALUE: '360' , CHANNEL_ID:201] 332 | } 333 | baidu { 334 | manifestPlaceholders = [CHANNEL_VALUE: 'baidu' , CHANNEL_ID:202] 335 | } 336 | } 337 | 338 | //修改生成的apk名字 339 | applicationVariants.all { variant -> 340 | variant.outputs.each { output -> 341 | def oldFile = output.outputFile 342 | if (variant.buildType.name.equals('release')) { 343 | def releaseApkName = getProductName() + "_v${defaultConfig.versionName}_${releaseTime()}_" + variant.productFlavors[0].name + '_release.apk' 344 | output.outputFile = new File(oldFile.parent, releaseApkName) 345 | } 346 | } 347 | } 348 | } 349 | 350 | //配置打包签名 351 | File propFile = file('signing.properties'); 352 | if (propFile.exists()) { 353 | def Properties props = new Properties() 354 | props.load(new FileInputStream(propFile)) 355 | if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') && 356 | props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) { 357 | android.signingConfigs.release.storeFile = file(props['STORE_FILE']) 358 | android.signingConfigs.release.storePassword = props['STORE_PASSWORD'] 359 | android.signingConfigs.release.keyAlias = props['KEY_ALIAS'] 360 | android.signingConfigs.release.keyPassword = props['KEY_PASSWORD'] 361 | } else { 362 | android.buildTypes.release.signingConfig = null 363 | } 364 | } else { 365 | android.buildTypes.release.signingConfig = null 366 | } 367 | 368 | dependencies { 369 | compile fileTree(dir: 'libs', include: ['*.jar']) 370 | compile 'com.android.support:appcompat-v7:21.0.3' 371 | compile 'com.umeng.analytics:analytics:latest.integration' 372 | //添加multidex的外部依赖jar包 373 | compile 'com.android.support:multidex:1.0.0' 374 | } 375 | 376 | 377 | ``` 378 | 379 | 下面给的整个打包流程图,可以让大家清晰的看到整个打包流程都做了些什么。 380 | 381 | ![整个打包流程图](http://a.hiphotos.baidu.com/image/pic/item/a71ea8d3fd1f4134af87467f231f95cad1c85e7a.jpg) 382 | 383 | 384 | 更多关于Gradle打包的详情,移步到官方的文档(**需要翻墙**)[官方原文请戳这里](http://tools.android.com/tech-docs/new-build-system/user-guide) 385 | 386 | 也可以直接在Github上看看随手记的开发者翻译出来的文档 [中文译本请戳这里](https://github.com/rujews/android-tech-docs/blob/master/new-build-system/user-guide/README.md) 387 | 388 | > **后续会再记录更多关于gradle使用的笔记,有兴趣的朋友敬请期待...** -------------------------------------------------------------------------------- /Android/Gradle/README.md: -------------------------------------------------------------------------------- 1 | # Gradle应用 2 | 3 | AndroidStudio和Gradle都风靡了,你还不快点学习? 4 | 5 | 6 | ## 电子书 7 | 8 | - [Building_and_Testing_with_Gradle](电子书/Building_and_Testing_with_Gradle.pdf) 9 | - [UserGuide](电子书/userguide.pdf) 10 | 11 | 12 | 13 | ## Gradle基础 14 | 15 | - [Gradle脚本基础(Android)](1_Gradle脚本基础(Android).md) 16 | - [Gradle语法基础解析](2_Gradle语法基础解析.md) 17 | - [ProGuard基础语法和打包配置](3_ProGuard基础语法和打包配置.md) 18 | - [AndroidStudio下ProGuard混淆打包](4_AndroidStudio下ProGuard混淆打包.md) 19 | - [Gradle多渠道和自动化打包(基础篇)](5_Gradle多渠道和自动化打包(基础篇).md) 20 | - [Gradle多渠道和自动化打包(深入篇)](6_Gradle多渠道和自动化打包(深入篇).md) 21 | 22 | ## 深度好文 23 | 24 | - [如何使用Android Studio把自己的Android library分发到jCenter和Maven Central](http://www.devtf.cn/?p=760) -------------------------------------------------------------------------------- /Android/Gradle/电子书/Building_and_Testing_with_Gradle.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-clock/Doc/1e2f29faba683344eff3893a1c5e936ddfd52dea/Android/Gradle/电子书/Building_and_Testing_with_Gradle.pdf -------------------------------------------------------------------------------- /Android/Gradle/电子书/userguide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-clock/Doc/1e2f29faba683344eff3893a1c5e936ddfd52dea/Android/Gradle/电子书/userguide.pdf -------------------------------------------------------------------------------- /Android/README.md: -------------------------------------------------------------------------------- 1 | # Android 2 | 3 | 个人Android开发的一些笔记,喜欢请拿走,疑惑请留问。 4 | 5 | ## 目录 6 | 7 | | 目录 | 简介 | 8 | |-------|----------| 9 | | [Gradle](Gradle) | Gradle的使用(AndroidStudio,Gradle打包) | 10 | | [实现原理](实现原理/) | 收藏记录一些系统实现原理,知其所以然 | 11 | | [图片处理](图片处理/) | 关于Android设备图片处理的相关知识 | 12 | | [辅助工具](辅助工具/) | 开发人员,怎么能没有一些神器 | 13 | | [性能优化](性能优化/) | 卡成翔,又耗电的应用死得快 | 14 | | [个人收藏](个人收藏/) | 喜欢就收藏... | -------------------------------------------------------------------------------- /Android/个人收藏/README.md: -------------------------------------------------------------------------------- 1 | # 个人收藏 2 | 3 | 收藏一些觉得丢了可惜的文章,自己偶尔可以回来翻翻看看... 4 | 5 | ## 热门话题 6 | 7 | - [知乎:有必要研究安卓源码吗?](https://www.zhihu.com/question/40126698/answer/85384588) 8 | - [知乎:Android开发,开始一个项目前,做好哪些准备可以事半功倍?](https://www.zhihu.com/question/37433825) 9 | - [知乎:Android开发中,有哪些坑需要注意?](https://www.zhihu.com/question/27818921) 10 | - [程序员怎样才能写出一篇好的博客或者技术文章](http://t.cn/RGOjHCQ) 11 | 12 | 13 | ## Android新特性 14 | 15 | - [Android L & M:巨人的进击 —— Android生态的破与立](http://yq.aliyun.com/articles/2324) 16 | 17 | 18 | ## ADB(Android Debug Bridge) 19 | 20 | - [adb操作命令文档(英文版)](http://adbshell.com/) 21 | - [Android 开发中常用 ADB 命令总结](http://t.cn/Rb35Ek7) -------------------------------------------------------------------------------- /Android/个人收藏/如何查看aar的源代码.md: -------------------------------------------------------------------------------- 1 | # 如何查看aar的源代码 2 | 3 | AndroidStudio中有一种aar格式的依赖包文件(和jar包差不多一样,就是能包含一些资源文件在其中),那么如果我们想看看其中源代码要怎么做呢?下面以我的开源项目 [AndroidStudyCode](https://github.com/D-clock/AndroidStudyCode) 为例子,简单演示一遍。 4 | 5 | 6 | - 将 **AndroidStudyCode** 以 **Import Module** 的形式导入,可以看到libs下存在aar文件 **AndroidUtils** 7 | 8 | ![](http://c.hiphotos.baidu.com/image/pic/item/b999a9014c086e06ffe53c9605087bf40bd1cb9a.jpg) 9 | 10 | - 找到 **AndroidStudyCode** 中某个调用 **AndroidUtils** 包中的方法,然后 **Ctrl+鼠标单击** 11 | 12 | ![](http://a.hiphotos.baidu.com/image/pic/item/91ef76c6a7efce1bd5fbc317a851f3deb58f651e.jpg) 13 | 14 | ![](http://a.hiphotos.baidu.com/image/pic/item/0b55b319ebc4b745f334c4cbc8fc1e178b82154e.jpg) 15 | 16 | 到此即可以看到源代码,此时的源码已经经过一定处理,没有了注释,而且有些地方还做了优化调整。为了能看到 **AndroidUtils** 中完整的源代码,我们需要找到它的源代码工程 [AndroidUtils](https://github.com/D-clock/AndroidUtils) , 将其下载到本地。接着开始点击下面的 **Choose Sources** 17 | 18 | ![](http://a.hiphotos.baidu.com/image/pic/item/b03533fa828ba61ec8b4b7f24634970a314e5990.jpg) 19 | 20 | 选中我们下载好的源码目录 21 | 22 | ![](http://d.hiphotos.baidu.com/image/pic/item/c9fcc3cec3fdfc03e9b19c65d33f8794a5c22625.jpg) 23 | 24 | 点击OK,可以看到下面的界面 25 | 26 | ![](http://c.hiphotos.baidu.com/image/pic/item/7dd98d1001e939010ba5f3e37cec54e737d19643.jpg) 27 | 28 | 再点击一次OK,即可看到下面的原封不动的源代码了 29 | 30 | ![](http://d.hiphotos.baidu.com/image/pic/item/d52a2834349b033b587a820712ce36d3d439bd78.jpg) 31 | 32 | 如果想要方便修改 **AndroidUtils** 中的源代码,并应用在 **AndroidStudyCode** 中,则可以参考以下的做法: 33 | 34 | 1、删除 libs 下的 **AndroidUtils** aar包,并去到 **AndroidStudyCode** 的 **build.gradle** 中移除aar配置 35 | 36 | ![](http://b.hiphotos.baidu.com/image/pic/item/2f738bd4b31c87011880d43b207f9e2f0708ff3d.jpg) 37 | 38 | 2、以 **Import Library** 的形式导入 **AndroidUtils** 的源代码,并在 **AndroidStudyCode** 的 **build.gradle** 添加以下配置信息 39 | 40 | ![](http://f.hiphotos.baidu.com/image/pic/item/d01373f082025aaf31661f16fcedab64024f1a92.jpg) 41 | 42 | 配置到此完成。 43 | -------------------------------------------------------------------------------- /Android/图片处理/01_各大图片加载框架的使用汇总.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-clock/Doc/1e2f29faba683344eff3893a1c5e936ddfd52dea/Android/图片处理/01_各大图片加载框架的使用汇总.md -------------------------------------------------------------------------------- /Android/图片处理/README.md: -------------------------------------------------------------------------------- 1 | # 图片处理 2 | 3 | 整理一下图片处理的知识点,包括框架的使用心得及相关的优化原理等 -------------------------------------------------------------------------------- /Android/实现原理/README.md: -------------------------------------------------------------------------------- 1 | # 实现原理 2 | 3 | 收录一些描述实现原理的深度好文... 4 | 5 | ## 当前收录 6 | 7 | - [开发技术前线(译):Binder解析](http://www.devtf.cn/?p=983) 8 | - [腾讯Bugly:浅析 Android 的窗口](http://t.cn/RbggwDF) 9 | -------------------------------------------------------------------------------- /Android/性能优化/01_Android系统那些重要的LOG.md: -------------------------------------------------------------------------------- 1 | # Android系统那些重要的LOG 2 | 3 | LOG对于开发者的重要性自然不必多提,今天主要来总结一下平时在开发过程中遇到的一些重要的LOG。这些LOG是Android系统自带打印的,巧妙的利用这些LOG能够帮助我们熟悉一个程序、排除故障以及做一些相应的性能优化工作。 4 | 5 | > **过滤这些LOG的方式是Android开发的程序猿都懂的,不再赘述~~~~~~** 6 | 7 | 8 | ## dalvikvm & ART 9 | 10 | 作为一名Android开发者,都知道是Dalvik和ART两个不同的虚拟机(Android开发者都不了解就要去厕所面壁了)。Android 4.4之前,都是只存在Dalvik虚拟机,而从Android4.4开始ART的虚拟机就已经存在,只不过需要手动进入系统设置里面切换到ART虚拟机运行环境。到Android5.0开始,系统就已经默认只用ART虚拟机。 11 | 12 | 如果你仔细观察过logcat,肯定可以看到下面这两类log(**log太长了,截不了全图,直接贴出来好了**) 13 | 14 | **Android 4.4.x及以下的版本可见** 15 | 16 | > ** com.tencent.mm D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms total 143.522ms** 17 | 18 | **Android 5.x及以上的版本可见** 19 | 20 | > ** com.tencent.mm I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms ** 21 | 22 | 系统的虚拟机打印出以上的log,目的是为了告诉我们一个app它对内存使用的变化情况。要利用这些log,首先就要弄明白它的信息含义。 23 | 24 | 先看dalvikvm的log格式信息含义,它的信息格式如下 25 | 26 | > ** PackageName D/dalvikvm: GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time Total_time ** 27 | 28 | | 名词 | 含义 | 29 | | -------- | -------- | 30 | | PackageName | 当前dalvik虚拟机属于哪个应用的,因为系统为每个app单独分配一个虚拟机 | 31 | | GC_Reason | 导致内存释放的原因,Dalvik虚拟机共有五类原因:GC_CONCURRENT、GC_FOR_MALLOC、GC_HPROF_DUMP_HEAP、GC_EXPLICIT、GC_EXTERNAL_ALLOC。 | 32 | | Amount_freed | 一次释放了多少内存 | 33 | | Heap_stats | 当前虚拟机堆内存的分配状态 | 34 | | External_memory_stats | Native堆内存的分配状态,这部分内存的分配回收不受虚拟机控制 | 35 | | Pause_time | GC线程垃圾搜集和释放引起的暂停时间,因为GC线程在做垃圾搜集和释放的时候,并发虚拟机会让其他Worker线程都挂起,让GC进行回收释放内存 | 36 | | Total_time | 整个GC流程的总耗时 | 37 | 38 | GC_Reason 又分为以下几类 39 | 40 | | 类型 | 含义 | 41 | | -------- | --------| 42 | | GC_CONCURRENT | 当前分配给app的内存开始被占满时,而触发此类GC。如果GC不能腾出内存,则会分配APP一个更大的堆内存。不断的重复前面两个操作,直到OOM为止。此类现象属于内存泄露了。 | 43 | | GC_FOR_MALLOC | 内存配额已满,GC_CONCURRENT类型的GC多次执行无效后触发此类GC。此时,系统强制停止app来回收内存 | 44 | | GC_HPROF_DUMP_HEAP | 在需要打印app的堆转储(HPROF)文件时候触发的GC,用于分析堆内存 | 45 | | GC_EXPLICIT | app显式调用System.gc时产生,Google是非常不建议开发者自行调用System.gc的 | 46 | | GC_EXTERNAL_ALLOC | Native堆内存的GC,如NIO和Bitmap像素的内存回收。这一类GC只有在API10及其以下的Android版本才能见到 | 47 | 48 | ** com.tencent.mm D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms total 143.522ms** 这行dalvikvm log想向我们表达的意思是微信这个app(com.tencent.mm就是微信的包名)此时需要用到的堆内存已经快占满分配堆内存,所以释放到2049K的内存。当前app分配的堆内存总大小9991K,其中有65%是可以使用的,3571K是当前被使用的。外部堆内存当前分配了5261K,已用了4703K。整个GC线程搜集垃圾和释放内存总耗时2ms+2ms(这段时间内其它Worker线程都暂停挂起),整个过程的总耗时是143.522ms。 49 | 50 | 再接着说说ART虚拟机的log,其格式含义如下: 51 | 52 | > **PackageName I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects, Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s) Total_time** 53 | 54 | | 名词 | 含义 | 55 | | -------- | -------- | 56 | | PackageName | 同上 | 57 | | GC_Reason | 同上,但ART虚拟机共有下面这些导致GC的类型:Concurrent、Alloc、Explicit、NativeAlloc、CollectorTransition、HomogeneousSpaceCompact、DisableMovingGc、HeapTrim | 58 | | GC_Name | GC的名称。总共有以下几种:Concurrent mark sweep (CMS)、Concurrent partial mark sweep、Concurrent sticky mark sweep、Marksweep + semispace | 59 | | Objects freed | 被回收的非大对象的个数 | 60 | | Size freed | 被回收的非大对象的总内存 | 61 | | Large objects freed | 被回收的大对象的个数 | 62 | | Large object size freed | 被回收的大对象的总内存 | 63 | | Heap stats | 同上 | 64 | | Pause_time | 同上 | 65 | | Total_time | 同上 | 66 | 67 | 68 | GC_Reason 又分为以下几类 69 | 70 | 71 | | 类型 | 含义 | 72 | | -------- | --------| 73 | | Concurrent | 后台并发类型的GC,不需要停止其他Worker线程,也不妨碍内存的分配。 | 74 | | Alloc | 此类GC是因分配给app的内存已经占满而触发,这时候GC发生在内存分配的线程 | 75 | | Explicit | app显式调用System.gc触发,同样不鼓励做这样的操作,因为ART下显式调用gc会造成线程分配被阻塞和占用更多的CPU周期,有可能引发app闪退 | 76 | | NativeAlloc | 由Native内存分配而出发的GC,如Bitmap或者RenderScript的内存分配 | 77 | | CollectorTransition | 由堆内存垃圾搜集时对象迁移而触发的GC,通常发生在app后台长期不使用时切换回前台使用的情况下产生 | 78 | | HomogeneousSpaceCompact | 整理堆内存随便而产生的GC,通常发生在app从前台的使用状态切换到后台长时间不使用的状态下发生,这样做好处是为了减少内存的使用而内存碎片的产生 | 79 | | DisableMovingGc | 这个并不是GC的原因,而是使用了GetPrimitiveArrayCritical引起的阻塞。一般情况下不建议使用GetPrimitiveArrayCritical的,因为会阻碍内存的移动而限制了垃圾搜集 | 80 | |HeapTrim| 同样不是GC的原因,但需要注意此时GC会被阻塞,直到堆内存的整理完成之后才会进行 | 81 | 82 | GC_Name 又分为以下几类 83 | 84 | | 类型 | 含义 | 85 | | -------- | --------| 86 | | Concurrent mark sweep (CMS) | 除了图片所占内存外,释放其他所有对象的内存空间 | 87 | | Concurrent partial mark sweep | 除了图片和zygote进程所占内存外,对其他所用内存空间做垃圾搜集 | 88 | | Concurrent sticky mark sweep | 分代垃圾搜集器只能释放上次GC时产生的对象,通常发生在对所有垃圾内存做搜集或对内存进行标记整理的时候, | 89 | | Marksweep + semispace | 非并发的复制类型GC,用于压缩整理堆内存的空间 | 90 | 91 | 大致总结到这里,后面ART那句LOG代表的意思,大致参照以上解释相信自己也能够看懂了,所以不再赘述。了解内存的变化有助于我们对app的性能调优,以上如果诸多不理解的话,就需要先学习一下虚拟机的运行机制了。 92 | 93 | ## Timeline 94 | 95 | 这个log如下图所示,为了方便,我直接拿微信朋友圈作为演示 96 | 97 | ![wechat](http://b.hiphotos.baidu.com/image/pic/item/ca1349540923dd54bfac21f9d709b3de9d824840.jpg) 98 | 99 | 我打开微信朋友圈的Activity(你随便打开哪个Activity都行),就会打印出一句log。这个log带给我们的信息有两个: 100 | 101 | * **朋友圈Activity名叫SnsTimeLineUI** 102 | * **它的全路径是com.tencent.mm.plugin.sns.ui.SnsTimeLineUI** 103 | 104 | 得知这两个对我们的意义在哪呢?大致如下几种场景会有所帮助: 105 | 106 | * **在新接触项目代码时,把项目跑起来后想知道哪个界面叫啥名就可以用到了,可以帮助快速熟悉项目代码;** 107 | * **在对某些项目做逆向工程分析时,可以快速定位到一个Activity界面,方便我们入手做分析工作;** 108 | * **可以直接跨app的调用应用的界面,例如可以在不使用微信的SDK的情况下,调用它的多图发朋友圈功能,当然如果还有涉及到权限或其他问题的话就需要再作分析进行调用了(因为是奇技淫巧,所以不赘述,普通开发也不推荐大家用,哈哈)** 109 | 110 | 111 | ## ActivityManager 112 | 113 | ActivityManager所带给我们的消息比较多,例如 114 | 115 | * 可以让我们了解各个堆栈信息 116 | 117 | ![ActivityManager Task Info](http://c.hiphotos.baidu.com/image/pic/item/960a304e251f95ca23ee6727cf177f3e6709520c.jpg) 118 | 119 | * 可以让我们了解哪些Activity被哪些信息出发弹出、哪些BroadcastReceiver接收哪些广播、哪些进程被强制停止或者直接kill 120 | 121 | ![ActivityManager Activity Broadcast Process Info](http://f.hiphotos.baidu.com/image/pic/item/6f061d950a7b02082eb1cd7064d9f2d3572cc823.jpg) 122 | 123 | * 可以让我们知道Service被杀死,和被重启,已经中间的耗时 124 | 125 | ![ActivityManager Service Info](http://g.hiphotos.baidu.com/image/pic/item/f703738da9773912ad4d54f0fe198618367ae23c.jpg) 126 | 127 | ## Choreographer 128 | 129 | 这个log在优化自定义View和Animation的时候,可以用到 130 | 131 | 如上图可以知道小米运动这个app某些界面出现了跳帧的现象,Choreographer提示我们,可能在app的ui线程做了太多事情导致了丢帧。这时候就可以考虑一下是否要优化了。 132 | 133 | ![Choreographer Info](http://a.hiphotos.baidu.com/image/pic/item/80cb39dbb6fd526638bfe785ad18972bd507368f.jpg) 134 | 135 | ## 总结 136 | 137 | 最后,本文的内容涉及到了一定的虚拟机方面(dalvikvm & ART)和自定义控件和动画方面(Choreographer)的知识,如果看不明白可能要先了解一下这些方面的知识点。好了,大致就总结了这些常用的log。当然,系统肯定还有其他一些目前我尚未发现到的,接下来如果看到一些有用的也会不断更新本文。其他有兴趣的开发者有空也可以多留意一下,说不定能在log中发现更多的惊喜,哈哈。 -------------------------------------------------------------------------------- /Android/性能优化/README.md: -------------------------------------------------------------------------------- 1 | # 性能优化 2 | 3 | 我眼中的性能优化宗旨:**人有我优,锱铢必较**,写下一些性能优化的心得,收录一些性能优化的干货。 4 | 5 | 6 | - [Android系统那些重要的LOG](01_Android系统那些重要的LOG.md) 7 | - [携程App的网络性能优化实践](http://t.cn/RGOpDEG) 8 | 9 | -------------------------------------------------------------------------------- /Android/辅助工具/AndroidStudio插件系列.md: -------------------------------------------------------------------------------- 1 | # AndroidStudio插件系列 2 | 3 | 终于有空来整理分享一下一些不错的AS插件了~~~ 4 | 5 | ## Genymotion 6 | 7 | Genymotion是测试Android应用程序,使你能够运行Android定制版本的旗舰工具。它是为了VirtualBox内部的执行而创建的,并配备了一整套与虚拟Android环境交互所需的传感器和功能。使用Genymotion能让你在多种虚拟开发设备上测试Android应用程序,并且它的模拟器比默认模拟器要快很多。 8 | 9 | https://www.genymotion.com/ 10 | 11 | ![Genymotion](http://g.hiphotos.baidu.com/image/pic/item/d009b3de9c82d15832cbc823860a19d8bd3e42d3.jpg) 12 | 13 | ## Android ButterKnife Zelezny 14 | 15 | Android ButterKnife是一个“Android视图注入库”。它提供了一个更好的代码视图,使之更具可读性。 ButterKnife能让你专注于逻辑,而不是胶合代码用于查找视图或增加侦听器。用ButterKnife编程,你必须对任意对象进行注入,注入形式是这样的: 16 | 17 | ```java 18 | @InjectView(R.id.title) TextView title; 19 | ``` 20 | 21 | ![ButterKnife](http://b.hiphotos.baidu.com/image/pic/item/30adcbef76094b3665c3887fa5cc7cd98c109dcb.jpg) 22 | 23 | https://github.com/avast/android-butterknife-zelezny 24 | 25 | > **一般情况下还是不建议用太多的注解** 26 | 27 | ## Robotium Recorder 28 | 29 | Robotium Recorder是一个自动化测试框架,用于测试在模拟器和Android设备上原生的和混合的移动应用程序。Robotium Recorder可以让你记录测试案例和用户操作。你也可以查看不同Android活动时的系统功能和用户测试场景。 30 | 31 | Robotium Recorder能让你看到当你的应用程序运行在设备上时,它是否能按预期工作,或者是否能对用户动作做出正确的回应。如果你想要开发稳定的Android应用程序,那么此插件对于进行彻底的测试很有帮助。 32 | 33 | ![Robotium Recorder](http://b.hiphotos.baidu.com/image/pic/item/03087bf40ad162d98b54f18e17dfa9ec8b13cdee.jpg) 34 | 35 | http://robotium.com/products/robotium-recorder 36 | 37 | > **要钱的哈,天朝找找破解** 38 | 39 | ## SelectorChapek 40 | 41 | 设计师给我们提供好了各种资源,每个按钮都要写一个selector是不是很麻烦?这么这个插件就为解决这个问题而生,你只需要做的是告诉设计师们按照规范命名就好了,其他一键搞定。 42 | 43 | ![SelectorChapek](http://e.hiphotos.baidu.com/image/pic/item/1ad5ad6eddc451daadd39f79b0fd5266d016327e.jpg) 44 | 45 | https://github.com/inmite/android-selector-chapek 46 | 47 | ## GsonFormat 48 | 49 | 现在大多数服务端api都以json数据格式返回,而客户端需要根据api接口生成相应的实体类,这个插件把这个过程自动化了,赶紧使用起来吧 50 | 51 | ![GsonFormat](http://f.hiphotos.baidu.com/image/pic/item/f7246b600c33874476a1bdee570fd9f9d72aa038.jpg) 52 | 53 | https://github.com/zzz40500/GsonFormat 54 | 55 | ## ParcelableGenerator 56 | 57 | Android中的序列化有两种方式,分别是实现Serializable接口和Parcelable接口,但在Android中是推荐使用Parcelable,只不过我们这种方式要比Serializable方式要繁琐,那么有了这个插件一切就ok了。 58 | 59 | ![ParcelableGenerator](http://c.hiphotos.baidu.com/image/pic/item/a08b87d6277f9e2f6d628f9a1930e924b999f3c9.jpg) 60 | 61 | https://github.com/mcharmas/android-parcelable-intellij-plugin 62 | 63 | ## SQLScout 64 | 65 | 一个黑科技的AS插件,有多黑,自己进主页围观膜拜吧!需要付费,有一个月的免费使用时间。天朝子民可以自己找破解方式了。 66 | 67 | http://www.idescout.com/ 68 | 69 | 70 | ## 总结 71 | 72 | 好了,大致就先到这里了,有nice的插件会继续更新... -------------------------------------------------------------------------------- /Android/辅助工具/Android反编译工具系列.md: -------------------------------------------------------------------------------- 1 | # Android反编译工具系列 2 | 3 | 对逆向分析有兴趣的朋友,应该会对这些工具感兴趣 4 | 5 | ## ApkTool 6 | 7 | 用于反编译apk,获取它的资源文件和配置文件. 8 | 9 | http://connortumbleson.com/ 10 | 11 | ## Dex2jar 12 | 13 | 对Android来说,可以翻译获取到项目源码。还有挺多其他功能,自行发掘吧. 14 | 15 | https://github.com/pxb1988/dex2jar 16 | 17 | ## JD_GUI 18 | 19 | 阅读反编译获取的源代码的工具软件,使用很简单 20 | 21 | https://github.com/java-decompiler/jd-gui 22 | 23 | ## Smali/Baksmali 24 | 25 | 反编译输出Dalvik汇编文件,应用于apk修改、补丁、破解等场合。喜欢破解折腾各类游戏的开发者应该很熟悉 26 | 27 | https://github.com/JesusFreke/smali 28 | 29 | ## Dedexer 30 | 31 | 反编译输出Dalvik汇编文件,功能同上,已经停更了一大段时间,后面估计会不行了吧。 32 | 33 | http://dedexer.sourceforge.net/ 34 | 35 | 36 | ## 总结 37 | 38 | > **大致就到这里了,有nice会继续更新...** 39 | 40 | -------------------------------------------------------------------------------- /Android/辅助工具/Android性能分析工具整理汇总.md: -------------------------------------------------------------------------------- 1 | # Android性能分析工具整理汇总 2 | 3 | 把做Android开发以来碰到的一些不错的性能分析工具做个整理汇总... 4 | 5 | ## Debug GPU Overdraw 6 | 7 | **类型**:系统自带功能UI渲染检测功能(**打开Settings,然后到 Developer Options -> Debug GPU Overdraw 选择 Show overdraw areas,手机系统设置中文的孩纸,自行对照翻译进去哈**) 8 | 9 | **作用**:用来检测UI的重绘次数,开发者可以用来优化UI的性能。 10 | 11 | **使用心得**:检测UI性能的利器,对于开发者做UI优化的帮助挺大的。因为大量的重绘容易让app造成卡顿或者直接导致丢帧的现象。开发者熟悉View的绘制原理可以结合对一些布局或者自定义控件做相应的优化。诸如:在ListView或GridView里面的item使用layout_weight设置就会造成多余重绘。其他情况还有很多,不一一例举。至于怎么用,可以自行Google 12 | 13 | ## Profile GPU Rendering 14 | 15 | **类型**:系统自带功能UI渲染检测功能(**打开Settings,然后到 Developer Options -> Profile GPU Rendering. 选择 On screen as bars **) 16 | 17 | **作用**:用来检测UI绘制帧的速率和耗时,同样开发者可以用来优化UI的性能。 18 | 19 | **使用心得**:跟Debug GPU Overdraw功能类似,但它反应的是UI绘制帧的速率,同样可以用来检测自己的app是否丢帧或者绘制过度,具体操作可以自行Google 20 | 21 | ## Hierarchy Viewer 22 | 23 | **类型**:SDK自带工具(**打开Settings,然后到 Developer Options -> Profile GPU Rendering. 选择 On screen as bars **) 24 | 25 | **作用**:检测UI渲染用的 26 | 27 | **使用心得**:老牌工具了,Google一下 28 | 29 | ## Memory Monitor、Heap Viewer、Allocation Tracker 30 | 31 | **类型**:AndroidStudio自带的工具 32 | 33 | **作用**:均是内存检测分析的工具 34 | 35 | **使用心得**:不用多说,大家懂的... 36 | 37 | ## Memory Analyzer Tool (MAT) 38 | 39 | **类型**:ADT时代的插件,也有独立的MAT版本 40 | 41 | **作用**:内存详尽分析的神器啊! 42 | 43 | **使用心得**:它是我在ADT下唯一的美好回忆啊,AS现在的工具就差它了,希望快点跟上。为了隆重介绍我的挚爱,果断献上它的官方文档:http://help.eclipse.org/mars/index.jsp 44 | 45 | ![MAT Doc](http://a.hiphotos.baidu.com/image/pic/item/b21bb051f819861846864c164ced2e738ad4e65b.jpg) 46 | 47 | ## Traceview、Systrace 48 | 49 | **类型**:SDK自带 50 | 51 | **作用**:CPU使用分析的工具 52 | 53 | **使用心得**:排除CPU性能瓶颈的利器,TraceView能让我知道个个函数调用的CPU耗时,以及总CPU耗时等,方便排查优化。Systrace能够让我了解各个AP子模块的使用情况,同样利于瓶颈排查,性能优化工作等,总之,很赞就是了。 54 | 55 | ## Battery Historian 56 | 57 | **类型**:独立开源软件 **(Google IO大会上的推荐的工具)** 58 | 59 | **作用**:耗电分析工具 60 | 61 | **使用心得**:在耗电分析上Google亲自推的东西自然不用说,Battery Historian 1.0的基本使用在网上挺多,可以自行查看。2.0的功能更加perfect,但是国内资料少,国外的资料算还可以,so,翻墙吧,骚年!使用 Battery Historian 需要注意两点,一是它只对5.x及其以上的系统生效,二是搭建环境的时候注意要使用Python2.x的,不要使用Python3.x。因为两个版本的语法变法很大,Python 3.x下Battery Historian会报错。最后,这个是开源项目 https://github.com/google/battery-historian 62 | 63 | -----------------------------------分割线----------------------------------- 64 | 65 | 上面主要都是官方的工具,下面是一些第三方apk工具... 66 | 67 | # WakeLock Detector 68 | 69 | **功能简介**:对手机的运行状态进行探测记录,能统计那些应用触发了CPU运行消耗cpu,那些应用触发了屏幕点亮。同时还可以对运行时间进行统计,可以查看应用内使用细节。 70 | 71 | **使用心得**:之前做了一款app被用户投诉耗电太快。偶然发现了它,拿做电量损耗检测。同时,它也能够统计其他安装在手机上的app的电量消耗,方便做出对比,向顶级体验的应用看齐。 72 | 73 | **使用前提**:手机需要root,该app需要获取root权限 74 | 75 | 76 | # GSam Battery Monitor 77 | 78 | **功能简介**:检测手机电池电量的消耗去向,能够用折线图进行统计展示。 79 | 80 | **使用心得**:不错的产品,能够计算出你的电量被手机的哪部分功能所消耗的,可以追溯到这部分功能是哪些app在使用,从而定位到手机耗电过快的元凶。 81 | 82 | **使用前提**:手机需要root,该app需要获取root权限 83 | 84 | # Trepn Profiler 85 | 86 | **功能简介**:高通出品的,杠杠的赞啊!分析检测手机CPU的消耗,而且能够分析特地的分析某个app。 87 | 88 | **使用心得**:用来调试分析自己的app,实时的用折线图展示了app对CPU的消费情况,赞赞赞。 89 | 90 | **使用前提**:手机需要root,该app需要获取root权限,且只支持手机的CPU是高通的。 91 | 92 | # Root Explorer 93 | 94 | **功能简介**:一款文件浏览器,可以查看app没有加密过的数据库,读取里面的数据,且支持简单的条件查询。 95 | 96 | **使用心得**:在开发的时候,需要确认是否成功把数据插入数据库,有了它就可以直接打开database文件浏览查找了。 97 | 98 | **使用前提**:手机需要root,该app需要获取root权限 99 | 100 | 101 | -----------------------------------分割线----------------------------------- 102 | 103 | 除了上面这些apk工具外,最后是一些知名IT公司开发的工具(包含SDK),很好用... 104 | 105 | ## Bugly 106 | 107 | 揪BUG、揪ANR的SDK。腾讯出品的东东,杠杠的。对发布出去的产品你想准确定位各种闪退的BUG,用它准行。而且bugly的更新频率还挺快的,大公司的效率真是任性(只能说鹅厂越来越会用技术赚钱了~~~~~) 108 | 109 | **官网地址**:http://bugly.qq.com/ 110 | 111 | ## BugTags 112 | 113 | 官网说的:测试,从未如此简单!新一代的、专为移动测试而生的缺陷发现及管理工具。个人觉得很不错,同样推荐! 114 | 115 | **官网地址**:https://bugtags.com/ 116 | 117 | ## GT 118 | 119 | 这款神器,可能并不多人知道(我猜的)。腾讯MIG专项测试组开发出来的狂拽酷炫屌炸天的神器,只要多神,不多说了,直接进去官网看吧,我已泪奔(腾讯的技术真心叼) 120 | 121 | **官网地址**:http://gt.tencent.com/index.html 122 | 123 | ## iTest 124 | 125 | 科大讯飞出品的测试工具,直接安装使用。是一款服务于Android测试人员的专业手机自动化性能监控工具。 126 | 127 | **官网地址**:http://itest.iflytesting.com/?p=1 128 | 129 | ## Emmagee 130 | 131 | 网易出品的测试工具,和iTest差不多,最大的好处在于,能够对应用的常用性能指标进行检测,并以csv的格式保存方便查看应用的各项参数。测试结果看起来更加直观,还有很重要一点是,它开源!!!! 132 | 133 | **官网地址**:https://github.com/NetEase/Emmagee 134 | 135 | 136 | ## 待续... 137 | 138 | 目前大体就这些了,后续有更好的工具也会接着更新,有些工具过时失效了,也会在这里移除... -------------------------------------------------------------------------------- /Android/辅助工具/README.md: -------------------------------------------------------------------------------- 1 | # 辅助工具 2 | 3 | 神器在手,效率我有。 4 | 5 | 6 | 7 | 8 | - [AndroidStudio插件系列](AndroidStudio插件系列.md) 9 | - [Android反编译工具系列](Android反编译工具系列.md) 10 | - [Android性能分析工具整理汇总](Android性能分析工具整理汇总.md) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chrome/README.md: -------------------------------------------------------------------------------- 1 | # Chrome 2 | 3 | Chrome死忠粉,边玩边记录... 4 | 5 | ## 常用命令 6 | 7 | 命令的具体功能不赘述,自己输进去玩一遍就知道!!!!!! 8 | 9 | 操作步骤: 10 | 11 | 1.打开 Chrome 12 | 2.在顶部的地址栏中输入命令 13 | 3.按 Enter 键 14 | 4.点击要打开的应用 15 | 16 | * chrome://extensions/ 17 | * chrome://apps/ 18 | 19 | ## 热门话题 20 | 21 | - [知乎:有哪些鲜为人知却非常有意思、好用的 Chrome 扩展?](https://www.zhihu.com/question/23228162) -------------------------------------------------------------------------------- /Code/Android编码命名规范.md: -------------------------------------------------------------------------------- 1 | # Android编码命名规范 2 | 3 | 今年正式本科毕业,目前为止参与过的团队开发项目也有四五个。阅读过各式各样的混乱代码,最离谱的见过所有的变量都用中文拼音首字母,心中真是万千匹草泥马在奔腾。由此,也意识到命名对于编码的重要性。有人说,看一个开发者的水平如何,从看他代码的命名可以大致得出结论。好的命名除了可以让项目成员快速且更好的理解代码,自己读起来也赏心悦目。为此,特地根据自己平常的一些编码规范和网上一些资料进行整理汇总,方便自己时常查看对比。 4 | 5 | ### 基本的命名法 6 | 7 | Java编程比较常见的有下面三种命名方式 8 | 9 | 1. 驼峰(Camel)命名法:又称小驼峰命名法,除首单词外,其余所有单词的第一个字母大写。 10 | 2. 帕斯卡(pascal)命名法:又称大驼峰命名法,所有单词的第一个字母大写 11 | 3. 下划线命名法:单词与单词间用下划线做间隔 12 | 13 | 一般建议拿来做命名的单词要比较精悍短小,这样即使两三个单词一起拼装成一个命名,也不至于显得很冗长。当然有些单词我们也可以直接写成一些约定俗成的缩写。诸如:msg(message)、init(initial)、img(image)等..... 14 | 15 | 个人认为,这些缩写可参照业界常见的缩写命名,也可以根据当前项目中的风格,进行团队成员间的约定。这样相对比较灵活,也方便团队成员之间相互理解。 16 | 17 | ### 包命名 18 | 19 | 采用反域名命名规则,全部使用小写字母。 20 | 21 | 1. 一级包名为com; 22 | 2. 二级包名为xx(可以是公司或则个人的随便); 23 | 3. 三级包名应用的英文名app_name; 24 | 4. 四级包名为模块名或层级名; 25 | 26 | 下面罗列一些常见的命名划分方式 27 | 28 | |命名格式| 作用 | 29 | |-------|----------| 30 | |com.xx.app_name.activities(或com.xx.app_name.activity)|存放app所有的Activity| 31 | |com.xx.app_name.service|存放app所有的Service| 32 | |com.xx.app_name.receiver|存放app所有的BroadcastReceiver| 33 | |com.xx.app_name.provider|存放app所有的ContentProvider| 34 | |com.xx.app_name.fragment|存放app所有的Fragment| 35 | |com.xx.app_name.dialog|存放app所有的Dialog| 36 | |com.xx.app_name.base|存放app一些共有的基础模块,诸如BaseActivity、BaseContentProvider、BaseService,BaseFragment等| 37 | |com.xx.app_name.utils|存放app的工具类,诸如格式化日期的DateFormatUtils,处理字符串的StringUtils等| 38 | |com.xx.app_name.bean(或com.xx.app_name.unity)|存放app自定义的实体类| 39 | |com.xx.app_name.db)|存放app数据库操作相关的类| 40 | |com.xx.app_name.view)|存放app自定义的控件| 41 | |com.xx.app_name.adapter)|存放app所有的适配器类| 42 | 43 | 44 | ### 类命名 45 | 46 | 名词,采用大驼峰命名法,尽量避免缩写,除非该缩写是众所周知的。如HTML,URL,JSON,XML等. 47 | 48 | |类|命名格式| 示例 | 49 | |-------|-------|----------| 50 | |Activity|XXX功能+Activity|如主界面HomeActivity,启动页LauncherActivity| 51 | |Service|XXX功能+Service|如消息推送的Service,PushService或PushMessageService| 52 | |BroadcastReceiver|XXX功能+Receiver|如在线的消息广播接受者,OnlineReceiver| 53 | |ContentProvider|XXX功能+Provider|如联系人的内容提供者,ContactsProvider| 54 | |Fragment|XXX功能+Fragment|如显示联系人的Fragment,ContactsFragment| 55 | |Dialog|XXX功能+Dialog|如普通的选择提示对话框,ChoiceDialog| 56 | |Adapter|XXX功能+XX类型控件Adapter|如联系人列表,ContactsListAdapter| 57 | |基础功能类|Base+XX父类名|如BaseActivity,BaseFragment| 58 | |工具类|XXX功能+Utils|如处理字符串的工具类,StringUtils| 59 | |管理类|XXX功能+Manager|如管理联系人的类,ContactsManager| 60 | 61 | 62 | ### 接口命名 63 | 64 | 和类名基本一致。也可以在接口名前面再加一个大写的I,表明这是一个接口Interface。 65 | 66 | 如:可以表明一个信息是否可以分享的接口,可以命名为Shareable,也可以是IShareable。 67 | 68 | ### 方法 69 | 70 | 动词或动名词,采用小驼峰命名法。 71 | 72 | 下面是一些比较常见的命名风格和含义 73 | 74 | |命名风格| 含义| 75 | |-------|----------| 76 | |initXX()|初始化,如初始化所有控件initView()| 77 | |isXX()|是否满足某种要求,如是否为注册用户isRegister()| 78 | |processXX()|对数据做某些处理,可以以process作为前缀| 79 | |displayXX()|显示提示信息,如displayXXDialog,displayToast,displayXXPopupWindow| 80 | |saveXX()|保存XX数据| 81 | |resetXX()|重置XX数据| 82 | |addXX()/insertXX()|添加XX数据| 83 | |deleteXX()/removeXX()|删除XX数据| 84 | |updateXX()|更新XX数据| 85 | |searchXX()/findXX()/queryXX()|查找XX数据| 86 | |draw()|控件里面使用居多,例如绘制文本drawText| 87 | 88 | 89 | ### 变量 90 | 91 | 采用小驼峰命名法。同样比较简单,但为了更好表明含义,我建议做一下的的区分 92 | 93 | - 成员变量命名前面加m(member,表示成员变量之意),如,控件的宽高 mWidth,mHeight 94 | - 静态类变量前面加s(static,表示静态变量之意),如,一个静态的单例 sSingleInstance 95 | 96 | 97 | ### 常量 98 | 99 | 同样较为简单,全部大写,采用下划线命名法.如:MIN_WIDTH,MAX_SIZE 100 | 101 | ### 布局资源文件(layout文件夹下) 102 | 103 | 全部小写,采用下划线命名法. 104 | 105 | 下面是一些比较常见的命名风格和含义 106 | 107 | |布局类型| 命名风格 | 108 | |-------|----------| 109 | |Activity的xml布局|activity_+XX功能,如主页面activity_home| 110 | |Fragment的xml布局|fragment_+XX功能,如联系人模块fragment_contacts| 111 | |Dialog的xml布局|dialog_+XX功能,如选择日期dialog_select_date| 112 | |抽取出来复用的xml布局(include)|include_+XX功能,如底部tab栏include_bottom_tabs| 113 | |ListView或者RecyclerView的item xml布局|XX功能+_list_item,如联系人的contact_info_list_item| 114 | |GridView的item xml布局|XX功能+_grid_item,如相册的album_grid_item| 115 | 116 | ### 动画资源文件(anim文件夹下) 117 | 118 | 全部小写,采用下划线命名法,加前缀区分. 119 | 120 | 下面是一些比较常见的命名风格和含义 121 | 122 | |动画效果| 命名风格 | 123 | |-------|----------| 124 | |淡入/淡出|fade_in/fade_out| 125 | |从某个方向淡入/淡出|fade_方向_in(out),右边淡入淡出fade_right_in(out)| 126 | |从某个方向弹入/弹出|push_方向_in(out),右边推入推出push_right_in(out)| 127 | |从某个方向滑入/滑出|slide_in(out)_from_方向,右边滑入滑出slide_in(out)_from_right| 128 | 129 | ### strings和colors资源文件 130 | 131 | 小驼峰命名法,命名风格大致如下: 132 | 133 | - string命名格式:XX界面_XX功能_str,如 activity_home_welcome_str 134 | - color命名格式:color_16进制颜色值,如红色 color_ff0000 135 | 136 | 像string通常建议把同一个界面的所有string都放到一起,方便查找。而color的命名则省去我们头疼的想这个颜色怎么命名。 137 | 138 | ### selecor、drawable、layer-list资源文件 139 | 140 | 小驼峰命名法。命名风格通常都是XX_selector、XX_drawable、XX_layer。 141 | 142 | 下面举两个比较常用的栗子: 143 | 144 | - 按钮按压效果button_selector,正常状态命名为button_normal(XX_normal),按压状态命名为button_pressed(XX_pressed) 145 | - 选择效果checkbox_selector,未选中状态命名为checkbox_unchecked(XX_unchecked),选中状态为checkbox_checked(XX_checked) 146 | 147 | 148 | ### styles、dimens资源文件 149 | 150 | - style采用大驼峰命名法,主题可以命名为XXTheme,控件的风格可以命名为XXStyle 151 | - dimen采用小驼峰命名法,如所有Activity的titlebar的高度,activity_title_height_dimen 152 | 153 | ### 控件id命名 154 | 155 | 因为有些控件平常不常用,所以上网搜罗了一份下来。集大家之所长,以作参考。 156 | 157 | |控件| 前缀缩写 | 158 | |-------|----------| 159 | |RelativeLayout| rl | 160 | |LinearLayout| ll | 161 | |FrameLayout| fl | 162 | |TextView| tv | 163 | |Button| btn | 164 | |ImageButton| imgBtn | 165 | |ImageView| imgView或iv | 166 | |CheckBox| chk | 167 | |RadioButton | rdoBtn | 168 | |analogClock| anaClk | 169 | |DigtalClock| dgtClk | 170 | |DatePicker| dtPk | 171 | |EditText | edtTxt或et | 172 | |TimePicker| tmPk | 173 | |toggleButton| tglBtn | 174 | |ProgressBar| proBar | 175 | |SeekBar | skBar | 176 | |AutoCompleteTextView| autoTxt | 177 | |ZoomControl| zmCtl | 178 | |VideoView| vdoVi | 179 | |WebView| webVi | 180 | |Spinner| spn | 181 | |Chronometer| cmt | 182 | |ScollView| sclVi | 183 | |TextSwitch| txtSwt | 184 | |ImageSwitch| imgSwt | 185 | |ListView| lv | 186 | |GridView| gv | 187 | |ExpandableList| epdLt | 188 | |MapView| mapVi | 189 | 190 | 以上就是从网上搜罗整理下来的,大家也可以做纠正或者补充。 191 | 192 | 193 | ## 总结 194 | 195 | 以上就是综合很多网上很多资料,再加上平时开发经验进行汇总整理的命名规范。好的命名规则能够提高代码质量,使得新人加入项目的时候降低理解代码的难度。最后我还要啰嗦一下几点: 196 | 197 | - 规矩终究是死的,适合团队的才是最好的 198 | - 命名规范需要团队一起齐心协力来维护执行,在团队生活里,谁都不可能独善其身 199 | - 如果你觉得你的命名晦涩难懂,那么,你可以开始动手了 200 | - 一开始总会不习惯的,一步一个脚印,持之以恒,总会成功的 201 | 202 | -------------------------------------------------------------------------------- /Code/README.md: -------------------------------------------------------------------------------- 1 | # Code 2 | 3 | 好代码可不仅仅只是实现了功能,你还需要... 4 | 5 | ## 编码规范 6 | 7 | - [Android编码命名规范](Android编码命名规范.md) 8 | - [Code Review最佳实践](http://mtydev.net/?p=59) 9 | 10 | 11 | ## 模块结构设计 12 | 13 | - [如何做客户端功能模块的设计](http://mtydev.net/?p=82) 14 | - [MVC,MVP和MVVM 的图示](http://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html) 15 | 16 | ## 重构 17 | 18 | - [关于烂代码的那些事(上)](http://blog.2baxb.me/archives/1343) 19 | - [关于烂代码的那些事(中)](http://blog.2baxb.me/archives/1378) 20 | - [关于烂代码的那些事(下)](http://blog.2baxb.me/archives/1499) -------------------------------------------------------------------------------- /Git/README.md: -------------------------------------------------------------------------------- 1 | # Git 2 | 3 | 整理收藏一些不错的文章,电子书,以及一些常见问题的解决方法 4 | 5 | 6 | **常见操作** 7 | 8 | - [常用的Git命令清单](http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html) 9 | - [Git如何忽略已经被提交的文件](http://segmentfault.com/q/1010000000430426) 10 | - [HTTPS和SSH方式的区别和使用](http://blog.csdn.net/d_clock/article/details/43762763) 11 | - [Submodule的应用(一)](http://blog.csdn.net/d_clock/article/details/43602699) 12 | - [Submodule的应用(二)](http://blog.csdn.net/d_clock/article/details/43730449) 13 | - [创建Pull Request](https://github.com/geeeeeeeeek/git-recipes/wiki/3.3-%E5%88%9B%E5%BB%BAPull-Request) 14 | - [github的pull request是指什么意思?](https://www.zhihu.com/question/21682976/answer/79489643) 15 | - [如何同步 Github fork 出来的分支](http://jinlong.github.io/2015/10/12/syncing-a-fork/) 16 | 17 | 18 | **电子书** 19 | 20 | - [Pro Git简体中文版在线电子书](http://iissnan.com/progit/) 21 | - [Git学习圣经《Pro Git 2nd》](http://git-scm.com/book/zh/v2) 22 | 23 | 24 | **原理解析** 25 | 26 | - [Git的工作方式和原理](http://www.ibm.com/developerworks/cn/devops/d-learn-workings-git/index.html) 27 | 28 | 29 | **疑难杂症处理方案** 30 | 31 | - [Windows环境TortosieGit安装后文件状态图标不能正常显示](http://blog.csdn.net/d_clock/article/details/43611421) -------------------------------------------------------------------------------- /IM/README.md: -------------------------------------------------------------------------------- 1 | # IM -------------------------------------------------------------------------------- /JavaWeb/00_服务器开发学习计划.md: -------------------------------------------------------------------------------- 1 | # 服务器开发学习计划 2 | 3 | 在大学里面是计算机专业,在刚开始选择开发方向的时候,一直在Android和服务器开发之间不断徘徊。后来综合考虑各种情况后,选择往属于前端的Android开发方面发展。今年15年毕业,在目前的公司工作到现在已经一年多,综合自己在Android客户端各方面开发取得的一些成果,以及我一直都希望能够充分的了解一套系统体系**(客户端+服务器,或者说前段+后台)**的搭建。为此,我决定了在兼顾好工作之余,开始弥补自己服务器方面知识的不足。今天主要记录一下自己做的大致计划(好记性不如烂键盘,嘻嘻...),也分享给其他有同样想法的朋友。 4 | 5 | 6 | ## 特别声明 7 | 8 | 需要特别的说明一下: 9 | 10 | ``` 11 | 以下是仅针对我本人情况所做的规划,其他有兴趣的朋友可以做个参考。请不要生搬硬套,毕竟适合你的才是最好的。 12 | 13 | ``` 14 | 15 | ## 大致计划 16 | 17 | 说起服务器开发的话,很多童鞋能罗列出一大堆要学习的语言出来,如做基本的: 18 | 19 | * 搭建网页结构需要**HTML**,高级点就**HTML5**了; 20 | * 来给网页润个色,你要会**CSS**; 21 | * 想来弄点高大上的动态交互效果之类的,**JavaScript**定是必备神器; 22 | * 处理数据爬取网页,你需要会**Python**; 23 | * 做服务器开发要选一门语言,**JSP**、**PHP**、**.NET**?; 24 | * 学校课本经常提到的,**SSH**三大框架; 25 | 26 | ![凌乱了](http://g.hiphotos.baidu.com/image/pic/item/30adcbef76094b36a20d4f4da5cc7cd98c109df6.jpg) 27 | 28 | 29 | 瞬间凌乱了有木有... 30 | 31 | 确实,初次看到这么多东西要学,真的头发瞬间凌乱了。但如果真要学,那也没办法,只能花些时间一个一个来。毕竟开发这东西不能急功近利,打好计划和基本功,日后技术自然扶摇直上妥妥滴。在面对前面列出的那么多语言后,我先对其做了大致的划分:**首先**,服务器开发人员需要掌握**前端**和**后端**两方面的知识。 32 | 33 | ## 前端 34 | 35 | 所谓**前端**,指的就是**客户端**或者**网页前端**。一般情况下,服务器开发人需要具备基本的编写网页的能力,所以**HTML**和**CSS**是肯定要学习的。如果你已经擅长开发客户端,可以优先学习一下后端的知识,这样就能很快的搭建一套自己的**服务器-客户端(C-S)**体系。但是要开发管理后台的话,还是避免不了要写网页页面,因此: 36 | 37 | * **做网页,HTML和CSS必学** 38 | 39 | 有了**HTML**和**CSS**之后,我们相当于有了一个像模像样的网页了。此时如果需要进行动态交互,那么就必须学习**JavaScript**了。针对**JavaScript**来说,我们可以选择比较流行的JS框架进行使用学习,例如**jQuery**.... 40 | 41 | * **动态交互,JavaScript必学** 42 | 43 | 到此我们已经实现了基本网页操作方面的功能,但这还不够。说好的服务器开发,只会弄个网页算个啥? 44 | 45 | ![你他妈在逗我](http://e.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494eedc1558b92bf5e0fe99257e5e.jpg) 46 | 47 | 所以,接下来就要开始接触学习后端知识了。 48 | 49 | ## 后端 50 | 51 | 说到学习后端,必然学习一门服务器开发技术。当下比较流行的技术无非就是**JSP**、**PHP**、**.NET**。这里选择哪一门就要看各人情况而定了,像我接触Java比较多,自然是学习JSP更佳节省时间。 52 | 53 | * **选择目前比较容易上手的服务器开发技术,以节省时间** 54 | 55 | 提到JSP,就必然想起教科书经常吹的**三大框架SSH**。其实出来工作后就会发现,三大框架在很多公司的开发中已经不受用了,例如**Spring**和**Struts**已经逐渐被**SpringMVC**取代,而且**SpringMVC**用起来更方便。除非你去维护一些旧的系统,它们一直沿用着**SSH**外,其他情况下基本都是**SpringMVC**的天下。另外,关于持久化储存的,就需要经常和数据库打交道,所以**Hibernate**框架需要会用,也可以考虑学习**MyBatis**。另外,关于缓存,你还要学习一下**Redis**的使用。 56 | 57 | 58 | * **选择JSP就需要学习SpringMVC** 59 | * **操作数据库需要Hibernate或者MyBatis** 60 | * **缓存的处理上需要会用Redis** 61 | 62 | 如果你要处理大量数据和爬虫,那还真的要考虑学学**Python**,感受一下它的魅力了。 63 | 64 | ## 小小的总结 65 | 66 | 做好了大致学习的计划后,就需要不断的不断的去重复实践。再根据自己的实际情况不断的调整自己的计划和方向,这样就可以一步一步的迈向下一个高度。 67 | 68 | **献给所有不断努力向上的程序猿们,晚安!** -------------------------------------------------------------------------------- /JavaWeb/README.md: -------------------------------------------------------------------------------- 1 | # JavaWeb 2 | 3 | 菜鸟一枚,笔记寥寥,大神请赐教。 4 | 5 | ## 目录 6 | 7 | | 标题 | 完成日期 | 8 | |----------|-------------| 9 | | [服务器开发学习计划](00_服务器开发学习计划.md) | 2015-10-02 | 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 3 | 自己写了一些平日里的开发总结,也把一些很难得的文章链接收藏进来。 4 | 5 | ## 最新更新 (编辑于2016-05-18) 6 | 7 | **Git** 下新增以下三篇: 8 | 9 | - [创建Pull Request](https://github.com/geeeeeeeeek/git-recipes/wiki/3.3-%E5%88%9B%E5%BB%BAPull-Request) 10 | - [github的pull request是指什么意思?](https://www.zhihu.com/question/21682976/answer/79489643) 11 | - [如何同步 Github fork 出来的分支](http://jinlong.github.io/2015/10/12/syncing-a-fork/) 12 | 13 | 14 | ## 目录 15 | 16 | | 目录 | 简介 | 17 | |-------|----------| 18 | | [Android](Android/) | Android开发知识的汇总 | 19 | | [Chrome](Chrome/) | Chrome死忠粉一枚 | 20 | | [Code](Code/) | 打代码也是有讲究的 | 21 | | [Git](Git/) | Git使用的一些汇总 | 22 | | [IM](IM/) | 对IM很感兴趣,不断的学习汇总 | 23 | | [JavaWeb](JavaWeb/) | 一直主攻Android,想慢慢接触后端的知识(算菜鸟笔记吧) | 24 | | [Team](Team/) | 关注一些团队协作的经验,站在巨人肩膀上摘苹果... | 25 | 26 | 27 | ## 更好的建议 28 | 29 | 如果你有好的建议或意见,请移步到[issues page](https://github.com/D-clock/Doc/issues) 或者给我的Gmail邮箱1084991652clock@gmail.com来封邮件吧.. 30 | 31 | ## 我的博客 32 | 33 | http://www.jianshu.com/users/ec95b5891948/latest_articles 34 | 35 | ## 我的微博 36 | 37 | ![weibo](http://f.hiphotos.baidu.com/image/pic/item/5366d0160924ab186240372432fae6cd7b890b4b.jpg) 38 | 39 | ## VPN 40 | 41 | 需要翻墙找资料的程序猿们,不妨买一个VPN。我自己用了云梯VPN有一年多了,觉得还不错,StackOverflow畅通无阻,Google+和Gmail正常用、开发资料更是福利多...如果有需要,不妨可以考虑点我的购买邀请链接: 42 | 43 | http://ugotvpn.com/?r=2c8df29b11aae81c 44 | 45 | 这样用满30天,你我都可以获得10块钱的优惠. -------------------------------------------------------------------------------- /Team/README.md: -------------------------------------------------------------------------------- 1 | # Team 2 | 3 | 关注一些关于团队建设,开发,管理方面的经验之谈. 4 | 5 | ## 热门话题 6 | 7 | - [知乎:怎么做好互联网公司的技术团队负责人?](https://www.zhihu.com/question/39421456) 8 | 9 | ## 致谢 10 | 11 | **非常感谢分享这些经验的大牛们!** --------------------------------------------------------------------------------