[TOC]
开始准备
导入包
1 | implementation 'com.jakewharton:butterknife:10.1.0' |
通过编写代码,在MainActivity布局中写一个textview, id叫tv
1 | public class MainActivity extends AppCompatActivity { |
在最后反编译apk的时候的图片

代码多出来个一个MainActivity_ViewBinding, 最关键的是这个类是怎么生成的了
查询了网上的资料通过 ButterKnifeProcessor 这个类来进行实现的
这个类继承至 AbstractProcessor
AbstractProcessor: 可以通过自定义自己的annotation,使得在编译源码代码阶段进行额外操作最后butterKnife 通过com.squareup.javapoet.JavaFile 写成一个java文件,
那就是MainActivity_ViewBinding.java等等一些类用过顶顶大名的Dagger,Butterknife等依赖注入的童鞋可能知道,他们就通过运行时annotation预处理技术实现动态的生成代码
apk瘦身三部曲, 图片,
删除
手动删除一些无用的代码
通过lint工具检测,然后删除一些无用的资源文件
gradle配置
压缩
png图片压缩
webp的使用
混淆
代码混淆
资源混淆
其他方法:
- 资源动态加载(如表情包动态下载)
- 插件化(动态加载)
手动删除无用代码
Lint工具检测
gradle 配置
1
2
3
4
5
6
7
8
9 android {
buildTypes {
release {
minifyEnabled true //是否开启混淆
shrinkResources true //压缩
zipAlignEnabled true ////去掉无用的resourse文件
}
}
}
动态代理
threadLocal 保证了 每个线程的looper一一对应
使变量的作用域可以是整个线程
Handler与ThreadLocal
在Android中,一个典型的ThreadLocal的使用场景就是Handler类的实现源码里,ThreadLocal用于存储当前线程的Looper对象,从而把线程和Looper对象实现一一对应的关系
asyncTask 源码解析
高效拼接一个字符串 使用 StringBuilder()
1 | txt_msg.setText(new StringBuilder().append("\n").append(msg).append("\n")); |
经典的自定义view的计算(计算weight下,左右需要padding,然后进行计算)
1 | WindowManager windowManager = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE); |