新聞中心
Android之LinkList
可以和ArrayList實(shí)現(xiàn)對(duì)比下 Android之ArrayList
創(chuàng)新互聯(lián)專業(yè)IDC數(shù)據(jù)服務(wù)器托管提供商,專業(yè)提供成都服務(wù)器托管,服務(wù)器租用,樂(lè)山服務(wù)器托管,樂(lè)山服務(wù)器托管,成都多線服務(wù)器托管等服務(wù)器托管服務(wù)。
ArrayList 實(shí)現(xiàn)多了一個(gè)AccessRondom 接口,少了Deque 接口
LinkList 實(shí)現(xiàn)多了Deque接口,少了AccessRandom接口
想了解AccessRandom接口可以參看 AccessRandom接口有啥用
Deque接口顧名思義,隊(duì)列,說(shuō)明LinkList 支持隊(duì)列操作
來(lái)看看內(nèi)部屬性
官方文檔對(duì)LinkList 的解釋是雙向鏈表,那么很容易理解這里保留first ,last 指針的意義了,就是為了方便雙向遍歷和插入
本身添刪改查沒(méi)有太多要說(shuō),注意下按索引遍歷,先是算下inde與size /2 比較下,然后決定是從頭部開(kāi)始遍歷還是尾部開(kāi)始遍歷。
android怎么實(shí)現(xiàn)任務(wù)隊(duì)列
主要就是有一個(gè)線程隊(duì)列,維護(hù)這些任務(wù),這里沒(méi)有用到Queue而是用List是考慮到顯示的問(wèn)題。
Android消息隊(duì)列淺析
當(dāng)面試官問(wèn)到你消息對(duì)列的時(shí)候,恭喜你,已經(jīng)跨過(guò)初級(jí),在試探你的中級(jí)水平了。
Android的消息循環(huán)是參考Windows的消息循環(huán)機(jī)制來(lái)實(shí)現(xiàn)的。
消息隊(duì)列4件套?? Message、MessageQueue、Looper、Handler
1、Message?是消息對(duì)列的消息實(shí)體類(lèi),因?yàn)橄㈥?duì)列中會(huì)存放最多10個(gè)Message對(duì)象。常用屬性?what,是消息體的Tag,用來(lái)區(qū)分是那個(gè)一消息體。
2、 MessageQueue? 先進(jìn)先出”的原則存放消息,將Message對(duì)象以鏈表的方式串聯(lián)起來(lái)。
3、Looper?是MessageQueue的管理者,主線程中是一對(duì)一的關(guān)系。子線程需要用到消息對(duì)列的話就需要經(jīng)典二人組 。先調(diào)用 Looper.prepare()方法,然后再調(diào)用Looper.loop();
4、Handler?是封裝和處理Message對(duì)象的。
通過(guò)源碼可知消息走向如下
handler.sendMessage()--handler.sendMessageDelayed()--handler.sendMessageAtTime()--msg.target = this;queue.enqueueMessage==把msg添加到消息隊(duì)列中
Android線程池的使用
在Android中有主線程和子線程的區(qū)分。主線程又稱為UI線程,主要是處理一些和界面相關(guān)的事情,而子線程主要是用于處理一些耗時(shí)比較大的一些任務(wù),例如一些網(wǎng)絡(luò)操作,IO請(qǐng)求等。如果在主線程中處理這些耗時(shí)的任務(wù),則有可能會(huì)出現(xiàn)ANR現(xiàn)象(App直接卡死)。
線程池,從名字的表明含義上我們知道線程池就是包含線程的一個(gè)池子,它起到新建線程、管理線程、調(diào)度線程等作用。
既然Android中已經(jīng)有了線程的概念,那么為什么需要使用線程池呢?我們從兩個(gè)方面給出使用線程池的原因。
在Android中線程池就是ThreadPoolExecutor對(duì)象。我們先來(lái)看一下ThreadPoolExecutor的構(gòu)造函數(shù)。
我們分別說(shuō)一下當(dāng)前的幾個(gè)參數(shù)的含義:
第一個(gè)參數(shù)corePoolSize為 核心線程數(shù) ,也就是說(shuō)線程池中至少有這么多的線程,即使存在的這些線程沒(méi)有執(zhí)行任務(wù)。但是有一個(gè)例外就是,如果在線程池中設(shè)置了allowCoreThreadTimeOut為true,那么在 超時(shí)時(shí)間(keepAliveTime) 到達(dá)后核心線程也會(huì)被銷(xiāo)毀。
第二個(gè)參數(shù)maximumPoolSize為 線程池中的最大線程數(shù) 。當(dāng)活動(dòng)線程數(shù)達(dá)到這個(gè)數(shù)后,后續(xù)添加的新任務(wù)會(huì)被阻塞。
第三個(gè)參數(shù)keepAliveTime為 線程的?;顣r(shí)間 ,就是說(shuō)如果線程池中有多于核心線程數(shù)的線程,那么在線程沒(méi)有任務(wù)的那一刻起開(kāi)始計(jì)時(shí),如果超過(guò)了keepAliveTime,還沒(méi)有新的任務(wù)過(guò)來(lái),則該線程就要被銷(xiāo)毀。同時(shí)如果設(shè)置了allowCoreThreadTimeOut為true,該時(shí)間也就是上面第一條所說(shuō)的 超時(shí)時(shí)間 。
第四個(gè)參數(shù)unit為 第三個(gè)參數(shù)的計(jì)時(shí)單位 ,有毫秒、秒等。
第五個(gè)參數(shù)workQueue為 線程池中的任務(wù)隊(duì)列 ,該隊(duì)列持有由execute方法傳遞過(guò)來(lái)的Runnable對(duì)象(Runnable對(duì)象就是一個(gè)任務(wù))。這個(gè)任務(wù)隊(duì)列的類(lèi)型是BlockQueue類(lèi)型,也就是阻塞隊(duì)列,當(dāng)隊(duì)列的任務(wù)數(shù)為0時(shí),取任務(wù)的操作會(huì)被阻塞;當(dāng)隊(duì)列的任務(wù)數(shù)滿了(活動(dòng)線程達(dá)到了最大線程數(shù)),添加操作就會(huì)阻塞。
第六個(gè)參數(shù)threadFactory為 線程工廠 ,當(dāng)線程池需要?jiǎng)?chuàng)建一個(gè)新線程時(shí),使用線程工廠來(lái)給線程池提供一個(gè)線程。
第七個(gè)參數(shù)handler為 拒絕策略 ,當(dāng)線程池使用有界隊(duì)列時(shí)(也就是第五個(gè)參數(shù)),如果隊(duì)列滿了,任務(wù)添加到線程池的時(shí)候的一個(gè)拒絕策略。
可以看到FixedThreadPool的構(gòu)建調(diào)用了ThreadPoolExecutor的構(gòu)造函數(shù)。從上面的調(diào)用中可以看出FixedThreadPool的幾個(gè)特點(diǎn):
可以看到CacheThreadPool的構(gòu)建調(diào)用了ThreadPoolExecutor的構(gòu)造函數(shù)。從上面的調(diào)用中可以看出CacheThreadPool的幾個(gè)特點(diǎn):
可以看到ScheduledThreadPoolExecutor的構(gòu)建調(diào)用了ThreadPoolExecutor的構(gòu)造函數(shù)。從上面的調(diào)用中可以看出ScheduledThreadPoolExecutor的幾個(gè)特點(diǎn):
可以看到SingleThreadExecutor的構(gòu)建調(diào)用了ThreadPoolExecutor的構(gòu)造函數(shù)。從上面的調(diào)用中可以看出SingleThreadExecutor的幾個(gè)特點(diǎn):
Android——消息分發(fā)機(jī)制
什么是 Handler 機(jī)制 ?
Handler 機(jī)制是 Android 中用于 線程間通信 的一套通信機(jī)制。
為什么是 Handler ?Handler 機(jī)制為什么被那么多次的提及 ?
從Android4.0開(kāi)始,Android 中網(wǎng)絡(luò)請(qǐng)求強(qiáng)制不允許在主線程中操作,而更新UI的操作則不允許在子線程中執(zhí)行。當(dāng)在子線程中執(zhí)行網(wǎng)絡(luò)請(qǐng)求,拿到服務(wù)器返回的數(shù)據(jù)之后,要更新UI。由于系統(tǒng)的要求,勢(shì)必會(huì)產(chǎn)生一種矛盾:數(shù)據(jù)在子線程,更新UI要在主線程。此時(shí)我們必須要把數(shù)據(jù)返回到主線程中才行,Handler機(jī)制應(yīng)運(yùn)而生。
Android 中針對(duì)耗時(shí)的操作,放在主線程操作,輕者會(huì)造成 UI 卡頓,重則會(huì)直接無(wú)響應(yīng),造成 Force Close。同時(shí)在 Android 3.0 以后,禁止在主線程進(jìn)行網(wǎng)絡(luò)請(qǐng)求。
針對(duì)耗時(shí)或者網(wǎng)絡(luò)操作,那就不能在主線程進(jìn)行直接操作了,需要放在子線程或者是工作線程中進(jìn)行操作,操作完成以后,再更新主線程即 UI 線程。這里就涉及到一個(gè)問(wèn)題了,在子線程執(zhí)行完成以后,怎么能更新到主線程即 UI 線程呢,針對(duì)以上問(wèn)題,就需要用到 Android 的消息機(jī)制了,即: Handler, Message, MessageQueue, Looper 全家桶
Handler機(jī)制中最重要的四個(gè)對(duì)象
Handler的構(gòu)造方法:
Looper :
Handler的使用:
MessageQueue:
Looper.loop()
Handler.dispatchMessage()
handler導(dǎo)致activity內(nèi)存泄露的原因:
handler發(fā)送的消息在當(dāng)前handler的消息隊(duì)列中,如果此時(shí)activity finish掉了,那么消息隊(duì)列的消息依舊會(huì)由handler進(jìn)行處理,若此時(shí)handler聲明為內(nèi)部類(lèi)(非靜態(tài)內(nèi)部類(lèi)),我們知道內(nèi)部類(lèi)天然持有外部類(lèi)的實(shí)例引用,這樣在GC垃圾回收機(jī)制進(jìn)行回收時(shí)發(fā)現(xiàn)這個(gè)Activity居然還有其他引用存在,因而就不會(huì)去回收這個(gè)Activity,進(jìn)而導(dǎo)致activity泄露。
假如在子線程執(zhí)行了耗時(shí)操作,這時(shí)用戶操作進(jìn)入了其他的 acitvity, 那么 MainActivity 就會(huì)被內(nèi)存回收的,但是這個(gè)時(shí)候發(fā)現(xiàn) Handler 還在引用著 MainActivity,內(nèi)存無(wú)法及時(shí)回收,造成內(nèi)存泄漏。
Handler 防止內(nèi)存泄漏常見(jiàn)方法:
為什么通過(guò) Handler 可以把子線程的結(jié)果通知或者攜帶給 UI 線程 ?
這里的 Handler 指的是主線程的 Handler ,同時(shí)與 Handler 配套的 Looper , MessageQueue 是在 UI 線程初始化的,所以在子線程中調(diào)用 Handler 發(fā)送消息可以更新 UI 線程。
Looper 在 UI 線程源碼, 在 ActivityThread 類(lèi):
當(dāng)前標(biāo)題:android隊(duì)列,Android隊(duì)列實(shí)戰(zhàn)例子
文章位置:http://fisionsoft.com.cn/article/dsgciso.html