2019-12-17

1.looper本身不会导致应用卡死,在onCreate,onResume,onStart等操作时间时间过长,会导致掉帧,甚至发生anr

android就是在Looper的loop循环的,整个android的一切都是以handler机制进行的,只要有代码执行都是通过handler执行的,所谓anr便是looper.loop没有得到及时处理,一旦没有消息,linux的epoll机制会通过管道文件描述的方式来对主线程进行唤醒与沉睡,android调用了linux层的代码实现在适当的时候进行休眠

android是事件驱动的,在looper.loop中不断的接收事件,处理事件,而activity的生命周期都依靠主线程的looper.loop来调度,所以可想而知他的存活周期和activity是一致的,当没有事件需要处理时,主线程就会阻塞,当子线程往消息队列中发送消息,并且往管道文件写数据时,主线程就被唤醒,因此looper循环并不会对cpu造成过多的消耗

主线程在没有事件需要处理的时候就处于阻塞状态,想让主线程活动起来,一般有两种方式:

1.系统唤醒主线程,并且将点击事件传给主线程

2.其他线程使用handler想messageQueue中发送一条消息,导致loop被唤醒继续执行

looper.loop可能会影响主线程阻塞,只要他的消息循环没有被阻塞,就不会产生anr。


2.handler是如何进行消息切换的

借助共享变量实现消息切换的。

在A线程中创建了handler,在B线程中调用handler发送一个message,当在A线程创建handler的时候,同时创建了messageQueue和looper对象,looper在A线程中通过loop进入到for循环从messageQueue中取消息,当B线程发送一个message时,通过msg.target.dispathMessage(msg),将message插入到对应的messageQueue中,looper发现有message插入到messageQueue中,便会从中取出message,应为looper.loop是在A线程中启动的,所以回到了A线程,达到了从A线程切换到B线程的目的

3.anr

activity最长执行时间是5s,广播最长执行时间是10s,serviceTimeOut最长执行时间是20s,超过这个时间就会实体anr

anr错误定位,通过adb命令,traceView定位耗时操作


4.cpu将UI对象转换为多维图形,通过openGl调用GPU,GPU栅格化显示在屏幕上

layoutInflater将xml展示在画面上,cpu计算xml中的布局,GPU栅格化的将像素点展示在屏幕上

卡顿原理分析(16ms主要被两件事占用)

(1)将UI对象转换成多边形和纹理

(2)CPU传递数据到GPU,GPU进行绘制。

减少卡顿的的时间

cpu减少xml转换对象的时间

GPU减少重复绘制(GPU很傻),gpu的绘制过程是根据cpu传递的指令来的,他很傻,让他画什么就画什么

过度绘制的几种情况

(1)布局层级太深

(2)自定义控件中,onDraw做了太多的绘制。


5.Butternife和ioc的区别

共同点:同样实现了解耦的原理

核心技术:运行时通过反射技术(relect) vs 注解处理器(apt)


6.ThreadLocal可以进行线程隔离。使用了弱引用,当key值遇到了gc的时候,会自动回收,避免内存泄露,使用remove方法,是当gc了之后,key被回收了,可以把那些没有访问的value给回收掉。

你可能感兴趣的:(2019-12-17)