2020.9.19 性能优化之UI优化
XML布局显示到屏幕上行的流程
CPU将UI对象转为多维图形 ---> 通过OpenGL调用GPU -----> GPU对图形进行栅格化 ---->显示器直接显示。
60Hz刷新频率由来
Android系统每隔16ms发出一个Vsync信号,触发对UI进行渲染,如果每次渲染都能成功,就能达到流畅的画面所需要的60fps,这就意味着,计算渲染的大多数操作都必须在16ms内完成。
如何减少时间
一、CPU减少xml转换成对象的时间:xml中减少布局层级;避免背景被重复绘制
二、GPU减少重复绘制;
优化是一种思想,而不是一套具体的方法,做UI优化的时候,可以从以下几个方面入手:
- 布局中的背景是否有必要;
- 自定义View是否进行了裁剪;
- 布局能否做到扁平化(是否可以删除多余布局);
- 当前页面是否存在非常耗内存的代码;
- WebView是否通过单开进程方式;
- 关于图片的计算是否需要动用代码;
内存抖动为什么会对UI产生卡顿
对象在堆中创建的时候,会先从年轻代的Eden区查找是否有内存空间,如果Eden区没有,则看下年轻代里s0、s1区是否有内存空间,如果有,则将Eden区里对象赶进s区,在Eden取给新对象分配空间,如果s区也没有空间,则去查看老年代区。一般新new的对象都是在Eden区域分配内存空间,除非new的对象比较大,直接超过了Eden区域的大小,这种大对象会直接被放在老年代。
内存的回收过程中,在做对象标记、筛选回收的时候,有可能暂停一会儿UI线程,所以说内存抖动可能产生UI卡顿。
假设ViewPager里有20个fragment,如何优化
优化的方案一定是扣空间或者时间。首先将每个fragment优化到极致(数据能不能少加载点?流程能不能优化?视觉能不能优化?);20个fragment能否少加载下?流程是否可优化?
2020.9.21 性能优化之运用设计模式优化代码结构
好的设计模式可以增强代码的可阅读性、易维护性、可扩展性。例如门面模式,我们在使用某个三方库(比如网络库)之前,可以先创建一个门面类,这个门面类是使用该三方库的唯一入口,这样就降低了业务逻辑和三方库的耦合度,一旦我们想更换三方库,只需要在门面类中修改即可。
然后在门面类中修改却不符合设计模式的开闭原则,什么是开闭原则呢,简单的讲就是,对修改关闭,对扩展开放。延续上面的例子,比如我们有一个VolleyFacade门面类,现在要将网络库更换为OkHttp,又不想违背开闭原则,那么我们可以先定义定义一个顶层接口IHttp,如下:
public interface IHttp{
void get(String url , Request request , Callback callback);
void post(String url , Request request , Callback callback);
}
然后VolleyFacade和OkHttpFacade分别实现IHttp接口。这种设计思想呢叫做设计模式的依赖倒置原则,顶层接口先定义好所需功能,至于怎么实现,交给下级各门面类处理。
那怎么使用这两个门面类呢,我们可以定义一个代理类,让这一个代理类,也实现IHttp接口,然后呢,外部向外部提供一个初始化方法,如下:
public class HttpProxy implements IHttp{
public static HttpProxy instance;
private IHttp iHttp;
private HttpProxy(){}
public static HttpProxy getInstance(){
if(instance == null){
synchronized(HttpProxy.class){
if(instance == null){
instance = HttpProxy();
}
}
}
return instance;
}
public void init(IHttp http){
iHttp = http;
}
@Override
public void get(...){
iHttp.get(...);
}
@Override
public void post(...){
iHttp.post(...);
}
}
这样,我们只需要在Application里初始化的时候,调用代理类的init方法,至于用哪个网络框架,由你传给init的参数决定。这样未来如果再有新的三方库要引入,我们要做的就是添加对应的门面类,修改代理类里的init方法的入参,也即修改一行代码即可。
2020.9.26 性能优化之全面瘦身优化
总结:
1.APK全面瘦身无非就是想方设法将APK的体积缩小,这个时候我们就需要去分析下当前应用的APK中有哪些资源是占了大头的,然后从这些地方入手。
2.一般可以被优化的地方就我们上课讲得图片优化、无用资源剔除、国际化资源配置优化、动态库打包优化、代码压缩/代码混淆、资源压缩/资源混淆等,其中比较重要的部分就是图片优化和so库优化,但是在优化中有很多细节大家要注意:比如图片优化后5.0以下兼容问题、代码混淆类找不到问题等。
3.除了我们今天讲的打包方案之外,其实还有两种比较牛的方案:
1.插件化开发(VIP架构课程会讲)
2.代码资源分离(参考网易云换肤框架课程)
结束语:优化之路路迢迢,但是只要我们不忽悠每一个细节,不多写一句废话代码,资源能重用就重用,能用系统自带的就用系统自带的,我们相信我们能够把APK优化的更好,加油!!!
2020.9.29 APK安全优化之APK加固防反编译
总结:
- APK加固其实可以理解为就是对APK里面的代码进行加密,我们的代码又是压缩在dex文件里面的,所以所谓的加固,就是以dex文件为对象进行加密。这里注意:很多同学认为混淆也是加密的一种,其实是不对的,它只是混淆了代码的文件名和类名等。
- 在加密过程中,要记住,包括apk、dex文件其实都是压缩文件,apk、dex文件其实都是压缩文件,aar、jar、library是可以通过工具方法去提取它里面的dex文件的(通过工具方法Dex.jarToDex()是去提取它里面的dex文件,并不是将整个jar包或者library直接转换为dex文件,因为dex文件只包含class文件,不包含资源,但是library里是有资源的)。
- 加密无非就是把原本的apk解压,然后把dex文件进行加密,再把用来解密的dex文件(壳)也存放在apk解压缩后的文件夹中,然后进行统一的签名打包。
- 解密算是加密的逆向,不一定非得怎么样加密就怎么样解密,只要解密算法写的好,什么方式都可以,所以加固的核心就是加密算法。解密不管如何实现,目的只有一个,即将加密的dex文件进行解密然后把解密后的dex让系统去加载(因为系统只会加载主包classes.dex),这里所用到的技术是动态加载技术,可以参考热修复。
启动优化
首先检查哪些方法耗时,可以使用Debug.startMethodTracing("test");+要检测的方法+Debug.stopMethedTracing()。执行以后,会在手机本地sd卡生成一个trace文件。改文件显示耗时信息。
也可以使用adb命令查看启动时间:adb shell am -w 包名.LaunchActivity.
将耗时方法,丢到线程里去执行。