Handler消息存儲(chǔ)機(jī)制
存值:
首先我們發(fā)送一個(gè)默認(rèn)消息時(shí)最終會(huì)走向MessageQueue的enqueMeassage()這個(gè)方法
首先會(huì)判斷如果隊(duì)列里無消息,或插入消息的執(zhí)行時(shí)間為0(強(qiáng)制插入隊(duì)頭),或插入消息的執(zhí)行
時(shí)間先于隊(duì)頭消息,這三種情況下插入消息為新隊(duì)頭,如果隊(duì)列被阻塞則將其喚醒 否則根據(jù)執(zhí)行時(shí)間將消息插入到隊(duì)列中間。通常我們不必喚醒事件隊(duì)列,除非隊(duì)列頭部有消息屏障阻塞隊(duì)列,并且插入的消息是隊(duì)列中第一個(gè)異步消息
取值:
MessageQueue.next()
該方法可以從消息隊(duì)列中取出一個(gè)需處理的消息,在沒有消息或者消息還未到時(shí)時(shí),該方法會(huì)阻塞線程,等待消息通過 MessageQueue.enqueueMessage() 方法入隊(duì)后喚醒線程。
MessageQueue的數(shù)據(jù)結(jié)構(gòu),是一個(gè)單向鏈表,Message對象有個(gè)next字段保存列表中的下一個(gè),MessageQueue中的mMessages保存鏈表的第一個(gè)元素。
總結(jié)一下MessageQueue獲取消息和加入消息的邏輯:
獲取消息:
1.首次進(jìn)入循環(huán)nextPollTimeoutMillis=0,阻塞方法nativePollOnce(ptr, nextPollTimeoutMillis)會(huì)立即返回
2.讀取列表中的消息,如果發(fā)現(xiàn)消息屏障,則跳過后面的同步消息,總之會(huì)通過當(dāng)前時(shí)間,是否遇到屏障來返回符合條件的待處理消息
3.如果沒有符合條件的消息,會(huì)處理一些不緊急的任務(wù)(IdleHandler),再次進(jìn)入第一步
加入消息:
1.加入消息比較簡單,按時(shí)間順序插入到消息鏈表中,如果是第一個(gè)那么根據(jù)mBlocked判斷是否需要喚醒線程,如果不是第一個(gè)一般情況下不需要喚醒(如果加入的消息是異步的需要另外判斷)
AsyncTask使用 以及內(nèi)部原理
使用場景:異步加載圖片、下載文件、單張圖片加載
使用方式:寫一個(gè)類繼承AsyncTask 需要填寫三個(gè)泛型:
Params 啟動(dòng)任務(wù)執(zhí)行的輸入?yún)?shù),比如下載URL
Progress 后臺(tái)任務(wù)執(zhí)行的百分比,比如下載進(jìn)度
Result 后臺(tái)執(zhí)行任務(wù)最終返回的結(jié)果,比如下載結(jié)果
Eventbus原理 粘性傳值原理
EventBus發(fā)送事件后是通過事件類型(或者叫做參數(shù)類型更好理解點(diǎn))來進(jìn)行匹配的。
當(dāng)我們使用粘性傳值時(shí):首先是先把我們發(fā)送的內(nèi)容保存到EventBus內(nèi)部中的一個(gè)HashMap中(初始化時(shí)候創(chuàng)建) 再通過EventBus post方法進(jìn)行傳值 當(dāng)我們從頁面A傳值給頁面B的時(shí)候,B頁面如果沒有被創(chuàng)建,我們就需要通過粘性傳值,將我們的數(shù)據(jù)先保存到我們的Map中當(dāng)我們頁面創(chuàng)建完成以后,再把我們保存在Map中的值進(jìn)行取出,就完成了這么一個(gè)傳值的效果。
Kotlin基本語法使用
var和val區(qū)別:
var是一個(gè)可變變量,這是一個(gè)可以通過重新分配來更改為另一個(gè)值的變量。這種聲明變量的方式和java中聲明變量的方式一樣。
val是一個(gè)只讀變量,這種聲明變量的方式相當(dāng)于java中的final變量。一個(gè)val創(chuàng)建的時(shí)候必須初始化,因?yàn)橐院蟛荒鼙桓淖?br>
返回值是在我們方法的參數(shù)后面通過:返回值類型 完成
fun:定義方法
Glide和Picasso區(qū)別 以及內(nèi)存緩存
Glide可以加載Gif圖,Picasso不可以
Glide加載圖片默認(rèn)加載當(dāng)前imageview大小,Picasso默認(rèn)加載全局圖片
Glide編碼RGB_565 Picasso編碼_8888
Glide內(nèi)存緩存的實(shí)現(xiàn)自然也是使用的LruCache算法。不過除了LruCache算法之外,Glide還結(jié)合了一種弱引用的機(jī)制,共同完成了內(nèi)存緩存功能
Google play上線
SharedPreferences兩種提交方式如何使用以及區(qū)別
2.editor.commit();
1.editor.apply();
區(qū)別:commit()返回boolean值驗(yàn)證是否提交成功 ;apply()第二種沒有返回值
commit()同步提交硬盤,容易造成線程堵塞;
apply()先提交到內(nèi)存,然后異步提交到磁盤;
volatile的作用
作用:
保證此變量對所有線程的可見性
簡單的說就是,當(dāng)一個(gè)線程修改了volatile變量之后,它先寫入它的工作內(nèi)存中,然后立刻寫入主內(nèi)存,并且刷新其他線程中的工作內(nèi)存,這樣其他線程再去讀取他們工作內(nèi)存中的變量時(shí),確保能夠拿到最新的。但是如果是普通變量的話,它不會(huì)立即寫入主內(nèi)存中,所有其他線程的工作內(nèi)存中保存的是舊的值。所有volatile變量可以保證可見性。禁止指令重排序優(yōu)化
1.當(dāng)后一個(gè)操作是volatile寫時(shí),不管前一個(gè)操作是什么(volatile讀/寫,普通變量讀/寫),都不能重排序。這個(gè)規(guī)則確保volatile寫之前的操作不會(huì)被編譯器重排序到volatile寫之后。
2.當(dāng)前一個(gè)操作是volatile讀時(shí), 不管后一個(gè)操作是什么,都不能重排序。這個(gè)規(guī)則確保volatile讀之后的操作不會(huì)被編譯器重排序到volatile讀之前。
3.當(dāng)前一個(gè)操作是volatile寫、后一個(gè)是volatile讀時(shí),不能重排序。