Handler消息存储机制
存值:
首先我们发送一个默认消息时最终会走向MessageQueue的enqueMeassage()这个方法
首先会判断如果队列里无消息,或插入消息的执行时间为0(强制插入队头),或插入消息的执行
时间先于队头消息,这三种情况下插入消息为新队头,如果队列被阻塞则将其唤醒 否则根据执行时间将消息插入到队列中间。通常我们不必唤醒事件队列,除非队列头部有消息屏障阻塞队列,并且插入的消息是队列中第一个异步消息
取值:
MessageQueue.next()
该方法可以从消息队列中取出一个需处理的消息,在没有消息或者消息还未到时时,该方法会阻塞线程,等待消息通过 MessageQueue.enqueueMessage() 方法入队后唤醒线程。
MessageQueue的数据结构,是一个单向链表,Message对象有个next字段保存列表中的下一个,MessageQueue中的mMessages保存链表的第一个元素。
总结一下MessageQueue获取消息和加入消息的逻辑:
获取消息:
1.首次进入循环nextPollTimeoutMillis=0,阻塞方法nativePollOnce(ptr, nextPollTimeoutMillis)会立即返回
2.读取列表中的消息,如果发现消息屏障,则跳过后面的同步消息,总之会通过当前时间,是否遇到屏障来返回符合条件的待处理消息
3.如果没有符合条件的消息,会处理一些不紧急的任务(IdleHandler),再次进入第一步
加入消息:
1.加入消息比较简单,按时间顺序插入到消息链表中,如果是第一个那么根据mBlocked判断是否需要唤醒线程,如果不是第一个一般情况下不需要唤醒(如果加入的消息是异步的需要另外判断)
AsyncTask使用 以及内部原理
使用场景:异步加载图片、下载文件、单张图片加载
使用方式:写一个类继承AsyncTask 需要填写三个泛型:
Params 启动任务执行的输入参数,比如下载URL
Progress 后台任务执行的百分比,比如下载进度
Result 后台执行任务最终返回的结果,比如下载结果
Eventbus原理 粘性传值原理
EventBus发送事件后是通过事件类型(或者叫做参数类型更好理解点)来进行匹配的。
当我们使用粘性传值时:首先是先把我们发送的内容保存到EventBus内部中的一个HashMap中(初始化时候创建) 再通过EventBus post方法进行传值 当我们从页面A传值给页面B的时候,B页面如果没有被创建,我们就需要通过粘性传值,将我们的数据先保存到我们的Map中当我们页面创建完成以后,再把我们保存在Map中的值进行取出,就完成了这么一个传值的效果。
Kotlin基本语法使用
var和val区别:
var是一个可变变量,这是一个可以通过重新分配来更改为另一个值的变量。这种声明变量的方式和java中声明变量的方式一样。
val是一个只读变量,这种声明变量的方式相当于java中的final变量。一个val创建的时候必须初始化,因为以后不能被改变
返回值是在我们方法的参数后面通过:返回值类型 完成
fun:定义方法
Glide和Picasso区别 以及内存缓存
Glide可以加载Gif图,Picasso不可以
Glide加载图片默认加载当前imageview大小,Picasso默认加载全局图片
Glide编码RGB_565 Picasso编码_8888
Glide内存缓存的实现自然也是使用的LruCache算法。不过除了LruCache算法之外,Glide还结合了一种弱引用的机制,共同完成了内存缓存功能
Google play上线
SharedPreferences两种提交方式如何使用以及区别
2.editor.commit();
1.editor.apply();
区别:commit()返回boolean值验证是否提交成功 ;apply()第二种没有返回值
commit()同步提交硬盘,容易造成线程堵塞;
apply()先提交到内存,然后异步提交到磁盘;
volatile的作用
作用:
-
保证此变量对所有线程的可见性
简单的说就是,当一个线程修改了volatile变量之后,它先写入它的工作内存中,然后立刻写入主内存,并且刷新其他线程中的工作内存,这样其他线程再去读取他们工作内存中的变量时,确保能够拿到最新的。但是如果是普通变量的话,它不会立即写入主内存中,所有其他线程的工作内存中保存的是旧的值。所有volatile变量可以保证可见性。 -
禁止指令重排序优化
1.当后一个操作是volatile写时,不管前一个操作是什么(volatile读/写,普通变量读/写),都不能重排序。这个规则确保volatile写之前的操作不会被编译器重排序到volatile写之后。
2.当前一个操作是volatile读时, 不管后一个操作是什么,都不能重排序。这个规则确保volatile读之后的操作不会被编译器重排序到volatile读之前。
3.当前一个操作是volatile写、后一个是volatile读时,不能重排序。








网友评论