成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

android代碼分析,安卓代碼分析

怎樣著手研究 Android 源代碼

不需要全部了解,閱讀你感興趣或者與你工作相關(guān)的部分就可以了。比如:

成都創(chuàng)新互聯(lián)專注于衡陽(yáng)企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),商城系統(tǒng)網(wǎng)站開(kāi)發(fā)。衡陽(yáng)網(wǎng)站建設(shè)公司,為衡陽(yáng)等地區(qū)提供建站服務(wù)。全流程按需定制網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

頂層目錄:

.

|– bionic (bionic庫(kù),Android的基礎(chǔ)庫(kù))

|– bootable (bootloader, recovery等,ROM移植相關(guān))

|– build (編譯和配置所需的腳本和工具)

|– dalvik (dalvik的Java虛擬機(jī))

|– development (開(kāi)發(fā)應(yīng)用程序所需的模板和工具)

|– external (由其他平臺(tái)移植過(guò)來(lái)的項(xiàng)目,對(duì)于移植工作是非常好的參考)

|– frameworks (應(yīng)用程序框架層,請(qǐng)仔細(xì)閱讀此部分代碼,對(duì)于開(kāi)發(fā)App會(huì)有很大幫助)

|– hardware (與硬件相關(guān)的庫(kù),驅(qū)動(dòng)開(kāi)發(fā)相關(guān))

|– kernel (linux內(nèi)核)

|– out (編譯后生成的目錄,包含構(gòu)建文件系統(tǒng)所需的文件)

|– packages (Android的原生應(yīng)用程序,App開(kāi)發(fā)者需要重點(diǎn)關(guān)注)

|– prebuilt (Android在各平臺(tái)下編譯的預(yù)置腳本)

|– system (Android的底層庫(kù))

`– vendor / device (設(shè)備相關(guān)的代碼,AOSP里不會(huì)有太多涉及,但是CM中卻是重點(diǎn))

external目錄:

.

|– aes (ASE加密)

|– apache-http (網(wǎng)頁(yè)服務(wù)器)

|– bison (自動(dòng)生成語(yǔ)法分析器,將無(wú)關(guān)文法轉(zhuǎn)換為C,C++)

|– bluez (Linux下的藍(lán)牙工具)

|– bsdiff (diff工具)

|– bzip2 (壓縮工具)

|– clearsilver (html模板系統(tǒng))

|– dbus (低延時(shí),低開(kāi)銷,高可用性的IPC機(jī)制)

|– dhcpcd (DHCP服務(wù))

|– dosfstools (DOS文件系統(tǒng)工具)

|– dropbear (SSH2的服務(wù)器/客戶端)

|– e2fsprogs (EXT2文件系統(tǒng)工具)

|– elfcopy (ELF復(fù)制工具)

|– elfutils (ELF工具)

|– embunit

|– emma (Java代碼覆蓋率統(tǒng)計(jì)工具)

|– esd (將多種音頻流混合在一個(gè)設(shè)備上播放)

|– expat

|– fdlibm

|– freetype (字體)

|– gdata (google的無(wú)線數(shù)據(jù))

|– genext2fs

|– giflib (gif庫(kù))

|– googleclient (google用戶庫(kù))

|– grub

|– icu4c

|– iptables (防火墻)

|– jdiff

|– jhead (jpeg頭部信息工具)

|– jpeg (jpeg庫(kù))

|– libffi

|– libpcap (網(wǎng)絡(luò)數(shù)據(jù)包捕獲函數(shù))

|– libpng (png庫(kù))

|– libxml2 (xml解析庫(kù))

|– netperf (網(wǎng)絡(luò)性能測(cè)試工具)

|– opencore (多媒體框架,最讓人詬病的模塊,Andoird 4.0中已被 stagefright 取代)

|– openssl (SSL模塊,需要注意的是一定要靜態(tài)編譯此模塊,否則會(huì)出現(xiàn)兼容問(wèn)題)

|– qemu (Android 模擬器,Android 4.0之前只支持 arm-eabi,現(xiàn)在已支持 arm-v7)

|– skia (SKIA圖像引擎)

|– sqlite (數(shù)據(jù)庫(kù))

|– strace (調(diào)試跟蹤工具)

|– tcpdump (TCP抓包軟件)

|– webkit (瀏覽器核心)

|– wpa_supplicant (無(wú)線網(wǎng)卡管理)

|– yaffs2 (yaffs文件系統(tǒng))

怎么分析android代碼是否存在內(nèi)存泄露

1、首先確定是否有內(nèi)存泄露及哪個(gè)程序造成。

1.1、內(nèi)存泄露已彈出out of memory對(duì)話框的情況。

這種情況很簡(jiǎn)單,直接看對(duì)話框就知道是哪個(gè)應(yīng)用的問(wèn)題了。然后再分析該應(yīng)用是否是因?yàn)閮?nèi)存泄露造成的

out of memory對(duì)話框。

》中介紹的各種方法進(jìn)行分析,確定是否有內(nèi)存泄露以及是哪個(gè)進(jìn)程造成的內(nèi)存泄露。

2、生成hprof文件,用MAT進(jìn)行分析。

成hprof文件可以在DDMS選中進(jìn)程點(diǎn)擊窗口左上角的dump hprof

file按鈕來(lái)直接生成,也可以通過(guò)在程序加代碼中來(lái)生成代碼2:voidgenerateHprof(){String

packageName=getApplicationInfo().packageName;

StringhpFilePath=/data/data/+packageName+/input.hprof;try{//Debug.dumpHprofData(/sdcard/input.hprof);Debug.

dumpHprofData

(hpFilePath);}catch(IOException e) {//TODOAuto-generated catch block

e.printStackTrace();}}建議使用代碼生成hprof,然后使用《

Android內(nèi)存泄露利器(hprof篇)》中的工具自動(dòng)提取多個(gè)hprof文件,然后用MAT進(jìn)行比較分析。在MAT導(dǎo)入.hprof文件以后,

MAT會(huì)自動(dòng)解析并生成報(bào)告,點(diǎn)擊

Dominator Tree

,并按Package分組,選擇自己所定義的Package類,比較各個(gè)類在不同時(shí)期的RetainedHeap

,找出可疑類,然后選擇該類,點(diǎn)右鍵,選中

show retained Set項(xiàng),參看Retained Heap

的詳細(xì)信息,進(jìn)一步找出嫌疑項(xiàng)。

3、在代碼中查找內(nèi)存泄露。

根據(jù)在MAT找到的內(nèi)存泄露信息,參照《

Android內(nèi)存泄漏簡(jiǎn)介

》進(jìn)一步在內(nèi)存中查找內(nèi)存泄露的原因并解決。

另外如果代碼很簡(jiǎn)單,可以直接參照《

Android內(nèi)存泄漏簡(jiǎn)介

》在內(nèi)存中查找內(nèi)存泄露的原因并解決。

《Android源碼分析實(shí)錄李忠良》pdf下載在線閱讀全文,求百度網(wǎng)盤(pán)云資源

《Android源碼分析實(shí)錄李忠良》百度網(wǎng)盤(pán)pdf最新全集下載:

鏈接:

?pwd=rt83 提取碼: rt83

簡(jiǎn)介:Android源碼分析實(shí)錄李忠良pdf全書(shū)共分為15章,分別講述了分析JNI層、Android內(nèi)存系統(tǒng)分析、Andmid虛擬機(jī)系統(tǒng)詳解、IPC通信機(jī)制詳解等,幫助讀者能一步一步了解Android系統(tǒng)核心源碼核心知識(shí)。 ?

Android源碼解析RPC系列(一)---Binder原理

看了幾天的Binder,決定有必要寫(xiě)一篇博客,記錄一下學(xué)習(xí)成果,Binder是Android中比較綜合的一塊知識(shí)了,目前的理解只限于JAVA層。首先Binder是干嘛用的?不用說(shuō),跨進(jìn)程通信全靠它,操作系統(tǒng)的不同進(jìn)程之間,數(shù)據(jù)不共享,對(duì)于每個(gè)進(jìn)程來(lái)說(shuō),它都天真地以為自己獨(dú)享了整個(gè)系統(tǒng),完全不知道其他進(jìn)程的存在,進(jìn)程之間需要通信需要某種系統(tǒng)機(jī)制才能完成,在Android整個(gè)系統(tǒng)架構(gòu)中,采用了大量的C/S架構(gòu)的思想,所以Binder的作用就顯得非常重要了,但是這種機(jī)制為什么是Binder呢?在Linux中的RPC方式有管道,消息隊(duì)列,共享內(nèi)存等,消息隊(duì)列和管道采用存儲(chǔ)-轉(zhuǎn)發(fā)方式,即數(shù)據(jù)先從發(fā)送方緩存區(qū)拷貝到內(nèi)核開(kāi)辟的緩存區(qū)中,然后再?gòu)膬?nèi)核緩存區(qū)拷貝到接收方緩存區(qū),這樣就有兩次拷貝過(guò)程。共享內(nèi)存不需要拷貝,但控制復(fù)雜,難以使用。Binder是個(gè)折中的方案,只需要拷貝一次就行了。其次Binder的安全性比較好,好在哪里,在下還不是很清楚,基于安全性和傳輸?shù)男士紤],選擇了Binder。Binder的英文意思是粘結(jié)劑,Binder對(duì)象是一個(gè)可以跨進(jìn)程引用的對(duì)象,它的實(shí)體位于一個(gè)進(jìn)程中,這個(gè)進(jìn)程一般是Server端,該對(duì)象提供了一套方法用以實(shí)現(xiàn)對(duì)服務(wù)的請(qǐng)求,而它的引用卻遍布于系統(tǒng)的各個(gè)進(jìn)程(Client端)之中,這樣Client通過(guò)Binder的引用訪問(wèn)Server,所以說(shuō),Binder就像膠水一樣,把系統(tǒng)各個(gè)進(jìn)程粘結(jié)在一起了,廢話確實(shí)有點(diǎn)多。

為了從而保障了系統(tǒng)的安全和穩(wěn)定,整個(gè)系統(tǒng)被劃分成內(nèi)核空間和用戶空間

內(nèi)核空間:獨(dú)立于普通的應(yīng)用程序,可以訪問(wèn)受保護(hù)的內(nèi)存空間,有訪問(wèn)底層硬件設(shè)備的所有權(quán)限。

用戶空間:相對(duì)與內(nèi)核空間,上層運(yùn)用程序所運(yùn)行的空間就是用戶空間,用戶空間訪問(wèn)內(nèi)核空間的唯一方式就是系統(tǒng)調(diào)用。一個(gè)4G的虛擬地址空間,其中3G是用戶空間,剩余的1G是內(nèi)核空間。如果一個(gè)用戶空間想與另外一個(gè)用戶空間進(jìn)行通信,就需要內(nèi)核模塊支持,這個(gè)運(yùn)行在內(nèi)核空間的,負(fù)責(zé)各個(gè)用戶進(jìn)程通過(guò)Binder通信的內(nèi)核模塊叫做Binder驅(qū)動(dòng),雖然叫做Binder驅(qū)動(dòng),但是和硬件并沒(méi)有什么關(guān)系,只是實(shí)現(xiàn)方式和設(shè)備驅(qū)動(dòng)程序是一樣的,提供了一些標(biāo)準(zhǔn)文件操作。

在寫(xiě)AIDL的時(shí)候,一般情況下,我們有兩個(gè)進(jìn)程,一個(gè)作為Server端提供某種服務(wù),然后另外一個(gè)進(jìn)程作為Client端,連接Server端之后,就 可以使用Server里面定義的服務(wù)。這種思想是一種典型的C/S的思想。值得注意的是Android系統(tǒng)中的Binder自身也是C/S的架構(gòu),也有Server端與Client端。一個(gè)大的C/S架構(gòu)中,也有一個(gè)小的C/S架構(gòu)。

先籠統(tǒng)的說(shuō)一下,在整個(gè)Binder框架中,由系列組件組成,分別是Client、Server、ServiceManager和Binder驅(qū)動(dòng)程序,其中Client、Server和ServiceManager運(yùn)行在用戶空間,Binder驅(qū)動(dòng)程序運(yùn)行內(nèi)核空間。運(yùn)行在用戶空間中的Client、Server和ServiceManager,是在三個(gè)不同進(jìn)程中的,Server進(jìn)程中中定義了服務(wù)提供給Client進(jìn)程使用,并且Server中有一個(gè)Binder實(shí)體,但是Server中定義的服務(wù)并不能直接被Client使用,它需要向ServiceManager注冊(cè),然后Client要用服務(wù)的時(shí)候,直接向ServiceManager要,ServiceManager返回一個(gè)Binder的替身(引用)給Client,這樣Client就可以調(diào)用Server中的服務(wù)了。

場(chǎng)景 :進(jìn)程A要調(diào)用進(jìn)程B里面的一個(gè)draw方法處理圖片。

分析 :在這種場(chǎng)景下,進(jìn)程A作為Client端,進(jìn)程B做為Server端,但是A/B不在同一個(gè)進(jìn)程中,怎么來(lái)調(diào)用B進(jìn)程的draw方法呢,首先進(jìn)程B作為Server端創(chuàng)建了Binder實(shí)體,為其取一個(gè)字符形式,可讀易記的名字,并將這個(gè)Binder連同名字以數(shù)據(jù)包的形式通過(guò)Binder驅(qū)動(dòng)發(fā)送給ServiceManager,也就是向ServiceManager注冊(cè)的過(guò)程,告訴ServiceManager,我是進(jìn)程B,擁有圖像處理的功能,ServiceManager從數(shù)據(jù)包中取出名字和引用以一個(gè)注冊(cè)表的形式保留了Server進(jìn)程的注冊(cè)信息。為什么是以數(shù)據(jù)包的形式呢,因?yàn)檫@是兩個(gè)進(jìn)程,直接傳遞對(duì)象是不行滴,只能是一些描述信息?,F(xiàn)在Client端進(jìn)程A聯(lián)系ServiceManager,說(shuō)現(xiàn)在我需要進(jìn)程B中圖像處理的功能,ServiceManager從注冊(cè)表中查到了這個(gè)Binder實(shí)體,但是呢,它并不是直接把這個(gè)Binder實(shí)體直接給Client,而是給了一個(gè)Binder實(shí)體的代理,或者說(shuō)是引用,Client通過(guò)Binder的引用訪問(wèn)Server。分析到現(xiàn)在,有個(gè)關(guān)鍵的問(wèn)題需要說(shuō)一下,ServiceManager是一個(gè)進(jìn)程,Server是另一個(gè)進(jìn)程,Server向ServiceManager注冊(cè)Binder必然會(huì)涉及進(jìn)程間通信。當(dāng)前實(shí)現(xiàn)的是進(jìn)程間通信卻又要用到進(jìn)程間通信,這就好象蛋可以孵出雞前提卻是要找只雞來(lái)孵蛋,確實(shí)是這樣的,ServiceManager中預(yù)先有了一個(gè)自己的Binder對(duì)象(實(shí)體),就是那只雞,然后Server有個(gè)Binder對(duì)象的引用,就是那個(gè)蛋,Server需要通過(guò)這個(gè)Binder的引用來(lái)實(shí)現(xiàn)Binder的注冊(cè)。雞就一只,蛋有很多,ServiceManager進(jìn)程的Binder對(duì)象(實(shí)體)僅有一個(gè),其他進(jìn)程所擁有的全部都是它的代理。同樣一個(gè)Server端Binder實(shí)體也應(yīng)該只有一個(gè),對(duì)應(yīng)所有Client端全部都是它的代理。

我們?cè)俅卫斫庖幌翨inder是什么?在Binder通信模型的四個(gè)角色里面;他們的代表都是“Binder”,一個(gè)Binder對(duì)象就代表了所有,包括了Server,Client,ServiceManager,這樣,對(duì)于Binder通信的使用者而言,不用關(guān)心實(shí)現(xiàn)的細(xì)節(jié)。對(duì)Server來(lái)說(shuō),Binder指的是Binder實(shí)體,或者說(shuō)是本地對(duì)象,對(duì)于Client來(lái)說(shuō),Binder指的是Binder代理對(duì)象,也就是Binder的引用。對(duì)于Binder驅(qū)動(dòng)而言,在Binder對(duì)象進(jìn)行跨進(jìn)程傳遞的時(shí)候,Binder驅(qū)動(dòng)會(huì)自動(dòng)完成這兩種類型的轉(zhuǎn)換。

簡(jiǎn)單的總結(jié)一下,通過(guò)上面一大段的分析,一個(gè)Server在使用的時(shí)候需要經(jīng)歷三個(gè)階段

1、定義一個(gè)AIDL文件

Game.aidl

GameManager .aidl

2、定義遠(yuǎn)端服務(wù)Service

在遠(yuǎn)程服務(wù)中的onBind方法,實(shí)現(xiàn)AIDL接口的具體方法,并且返回Binder對(duì)象

3、本地創(chuàng)建連接對(duì)象

以上就是一個(gè)遠(yuǎn)端服務(wù)的一般套路,如果是在兩個(gè)進(jìn)程中,就可以進(jìn)程通信了,現(xiàn)在我們分析一下,這個(gè)通信的流程。重點(diǎn)是GameManager這個(gè)編譯生成的類。

從類的關(guān)系來(lái)看,首先接口GameManager 繼承 IInterface ,IInterface是一個(gè)接口,在GameManager內(nèi)部有一個(gè)內(nèi)部類Stub,Stub繼承了Binder,(Binder實(shí)現(xiàn)了IBinder),并且實(shí)現(xiàn)了GameManager接口,在Stub中還有一個(gè)內(nèi)部類Proxy,Proxy也實(shí)現(xiàn)了GameManager接口,一個(gè)整體的結(jié)構(gòu)是這樣的

現(xiàn)在的問(wèn)題是,Stub是什么?Proxy又是什么?在上面說(shuō)了在Binder通信模型的四個(gè)角色里面;他們的代表都是“Binder”,一個(gè)Binder對(duì)象就代表了所有,包括了Server,Clinet,ServiceManager,為了兩個(gè)進(jìn)程的通信,系統(tǒng)給予的內(nèi)核支持是Binder,在抽象一點(diǎn)的說(shuō),Binder是系統(tǒng)開(kāi)辟的一塊內(nèi)存空間,兩個(gè)進(jìn)程往這塊空間里面讀寫(xiě)數(shù)據(jù)就行了,Stub從Binder中讀數(shù)據(jù),Proxy向Binder中寫(xiě)數(shù)據(jù),達(dá)到進(jìn)程間通信的目的。首先我們分析Stub。

Stub 類繼承了Binder ,說(shuō)明了Stub有了跨進(jìn)程傳輸?shù)哪芰?,?shí)現(xiàn)了GameManager接口,說(shuō)明它有了根據(jù)游戲ID查詢一個(gè)游戲的能力。我們?cè)赽ind一個(gè)Service之后,在onServiceConnecttion的回調(diào)里面,就是通過(guò)asInterface方法拿到一個(gè)遠(yuǎn)程的service的。

asInterface調(diào)用queryLocalInterface。

mDescriptor,mOwner其實(shí)是Binder的成員變量,Stub繼承了Binder,在構(gòu)造函數(shù)的時(shí)候,對(duì)著兩個(gè)變量賦的值。

如果客戶端和服務(wù)端是在一個(gè)進(jìn)程中,那么其實(shí)queryLocalInterface獲取的就是Stub對(duì)象,如果不在一個(gè)進(jìn)程queryLocalInterface查詢的對(duì)象肯定為null,因?yàn)椴煌M(jìn)程有不同虛擬機(jī),肯定查不到mOwner對(duì)象的,所以這時(shí)候其實(shí)是返回的Proxy對(duì)象了。拿到Stub對(duì)象后,通常在onServiceConnected中,就把這個(gè)對(duì)象轉(zhuǎn)換成我們多定義AIDL接口。

比如我們這里會(huì)轉(zhuǎn)換成GameManager,有了GameManager對(duì)象,就可以調(diào)用后querryGameById方法了。如果是一個(gè)進(jìn)程,那直接調(diào)用的是自己的querryGameById方法,如果不是一個(gè)進(jìn)程,那調(diào)用了就是代理的querryGameById方法了。

看到其中關(guān)鍵的一行是

mRemote就是一個(gè)IBinder對(duì)象,相對(duì)于Stub,Proxy 是組合關(guān)系(HAS-A),內(nèi)部有一個(gè)IBinder對(duì)象mRemote,Stub是繼承關(guān)系(IS-A),直接實(shí)現(xiàn)了IBinder接口。

transact是個(gè)native方法,最終還會(huì)回掉JAVA層的onTransact方法。

onTransact根據(jù)調(diào)用號(hào)(每個(gè)AIDL函數(shù)都有一個(gè)編號(hào),在跨進(jìn)程的時(shí)候,不會(huì)傳遞函數(shù),而是傳遞編號(hào)指明調(diào)用哪個(gè)函數(shù))調(diào)用相關(guān)函數(shù);在這個(gè)例子里面,調(diào)用了Binder本地對(duì)象的querryGameById方法;這個(gè)方法將結(jié)果返回給驅(qū)動(dòng),驅(qū)動(dòng)喚醒掛起的Client進(jìn)程里面的線程并將結(jié)果返回。于是一次跨進(jìn)程調(diào)用就完成了。

***Please accept mybest wishes for your happiness and success ! ***

[Android源碼分析] - 異步通信Handler機(jī)制

一、問(wèn)題:在Android啟動(dòng)后會(huì)在新進(jìn)程里創(chuàng)建一個(gè)主線程,也叫UI線程( 非線程安全 )這個(gè)線程主要負(fù)責(zé)監(jiān)聽(tīng)屏幕點(diǎn)擊事件與界面繪制。當(dāng)Application需要進(jìn)行耗時(shí)操作如網(wǎng)絡(luò)請(qǐng)求等,如直接在主線程進(jìn)行容易發(fā)生ANR錯(cuò)誤。所以會(huì)創(chuàng)建子線程來(lái)執(zhí)行耗時(shí)任務(wù),當(dāng)子線程執(zhí)行完畢需要通知UI線程并修改界面時(shí),不可以直接在子線程修改UI,怎么辦?

解決方法:Message Queue機(jī)制可以實(shí)現(xiàn)子線程與UI線程的通信。

該機(jī)制包括Handler、Message Queue、Looper。Handler可以把消息/ Runnable對(duì)象 發(fā)給Looper,由它把消息放入所屬線程的消息隊(duì)列中,然后Looper又會(huì)自動(dòng)把消息隊(duì)列里的消息/Runnable對(duì)象 廣播 到所屬線程里的Handler,由Handler處理接收到的消息或Runnable對(duì)象。

1、Handler

每次創(chuàng)建Handler對(duì)象時(shí),它會(huì)自動(dòng)綁定到創(chuàng)建它的線程上。如果是主線程則默認(rèn)包含一個(gè)Message Queue,否則需要自己創(chuàng)建一個(gè)消息隊(duì)列來(lái)存儲(chǔ)。

Handler是多個(gè)線程通信的信使。比如在線程A中創(chuàng)建AHandler,給它綁定一個(gè)ALooper,同時(shí)創(chuàng)建屬于A的消息隊(duì)列AMessageQueue。然后在線程B中使用AHandler發(fā)送消息給ALooper,ALooper會(huì)把消息存入到AMessageQueue,然后再把AMessageQueue廣播給A線程里的AHandler,它接收到消息會(huì)進(jìn)行處理。從而實(shí)現(xiàn)通信。

2、Message Queue

在主線程里默認(rèn)包含了一個(gè)消息隊(duì)列不需要手動(dòng)創(chuàng)建。在子線程里,使用Looper.prepare()方法后,會(huì)先檢查子線程是否已有一個(gè)looper對(duì)象,如果有則無(wú)法創(chuàng)建,因?yàn)槊總€(gè)線程只能擁有一個(gè)消息隊(duì)列。沒(méi)有的話就為子線程創(chuàng)建一個(gè)消息隊(duì)列。

Handler類包含Looper指針和MessageQueue指針,而Looper里包含實(shí)際MessageQueue與當(dāng)前線程指針。

下面分別就UI線程和worker線程講解handler創(chuàng)建過(guò)程:

首先,創(chuàng)建handler時(shí),會(huì)自動(dòng)檢查當(dāng)前線程是否包含looper對(duì)象,如果包含,則將handler內(nèi)的消息隊(duì)列指向looper內(nèi)部的消息隊(duì)列,否則,拋出異常請(qǐng)求執(zhí)行l(wèi)ooper.prepare()方法。

- 在 UI線程 中,系統(tǒng)自動(dòng)創(chuàng)建了Looper 對(duì)象,所以,直接new一個(gè)handler即可使用該機(jī)制;

- 在 worker線程 中,如果直接創(chuàng)建handler會(huì)拋出運(yùn)行時(shí)異常-即通過(guò)查‘線程-value’映射表發(fā)現(xiàn)當(dāng)前線程無(wú)looper對(duì)象。所以需要先調(diào)用Looper.prepare()方法。在prepare方法里,利用ThreadLocalLooper對(duì)象為當(dāng)前線程創(chuàng)建一個(gè)Looper(利用了一個(gè)Values類,即一個(gè)Map映射表,專為thread存儲(chǔ)value,此處為當(dāng)前thread存儲(chǔ)一個(gè)looper對(duì)象)。然后繼續(xù)創(chuàng)建handler, 讓handler內(nèi)部的消息隊(duì)列指向該looper的消息隊(duì)列(這個(gè)很重要,讓handler指向looper里的消息隊(duì)列,即二者共享同一個(gè)消息隊(duì)列,然后handler向這個(gè)消息隊(duì)列發(fā)送消息,looper從這個(gè)消息隊(duì)列獲取消息) 。然后looper循環(huán)消息隊(duì)列即可。當(dāng)獲取到message消息,會(huì)找出message對(duì)象里的target,即原始發(fā)送handler,從而回調(diào)handler的handleMessage() 方法進(jìn)行處理。

- handler與looper共享消息隊(duì)列 ,所以handler發(fā)送消息只要入列,looper直接取消息即可。

- 線程與looper映射表 :一個(gè)線程最多可以映射一個(gè)looper對(duì)象。通過(guò)查表可知當(dāng)前線程是否包含looper,如果已經(jīng)包含則不再創(chuàng)建新looper。

5、基于這樣的機(jī)制是怎樣實(shí)現(xiàn)線程隔離的,即在線程中通信呢。?

核心在于 每一個(gè)線程擁有自己的handler、message queue、looper體系 。而 每個(gè)線程的Handler是公開(kāi) 的。B線程可以調(diào)用A線程的handler發(fā)送消息到A的共享消息隊(duì)列去,然后A的looper會(huì)自動(dòng)從共享消息隊(duì)列取出消息進(jìn)行處理。反之一樣。

二、上面是基于子線程中利用主線程提供的Handler發(fā)送消息出去,然后主線程的Looper從消息隊(duì)列中獲取并處理。那么還有另外兩種情況:

1、主線程發(fā)送消息到子線程中;

采用的方法和前面類似。要在子線程中實(shí)例化AHandler并設(shè)定處理消息的方法,同時(shí)由于子線程沒(méi)有消息隊(duì)列和Looper的輪詢,所以要加上Looper.prepare(),Looper.loop()分別創(chuàng)建消息隊(duì)列和開(kāi)啟輪詢。然后在主線程中使用該AHandler去發(fā)送消息即可。

2、子線程A與子線程B之間的通信。

1、 Handler為什么能夠?qū)崿F(xiàn)不同線程的通信?核心點(diǎn)在哪?

不同線程之間,每個(gè)線程擁有自己的Handler、消息隊(duì)列和Looper。Handler是公共的,線程可以通過(guò)使用目標(biāo)線程的Handler對(duì)象來(lái)發(fā)送消息,這個(gè)消息會(huì)自動(dòng)發(fā)送到所屬線程的消息隊(duì)列中去,線程自帶的Looper對(duì)象會(huì)不斷循環(huán)從里面取出消息并把消息發(fā)送給Handler,回調(diào)自身Handler的handlerMessage方法,從而實(shí)現(xiàn)了消息的線程間傳遞。

2、 Handler的核心是一種事件激活式(類似傳遞一個(gè)中斷)的還是主要是用于傳遞大量數(shù)據(jù)的?重點(diǎn)在Message的內(nèi)容,偏向于數(shù)據(jù)傳輸還是事件傳輸。

目前的理解,它所依賴的是消息隊(duì)列,發(fā)送的自然是消息,即類似事件中斷。

0、 Android消息處理機(jī)制(Handler、Looper、MessageQueue與Message)

1、 Handler、Looper源碼閱讀

2、 Android異步消息處理機(jī)制完全解析,帶你從源碼的角度徹底理解

謝謝!

wingjay

![](;s=460)

網(wǎng)站題目:android代碼分析,安卓代碼分析
轉(zhuǎn)載來(lái)源:http://jinyejixie.com/article44/hojiee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開(kāi)發(fā)、做網(wǎng)站電子商務(wù)、建站公司外貿(mào)建站、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
平安县| 仙桃市| 阿图什市| 弋阳县| 鄂托克旗| 日土县| 灵寿县| 长宁区| 潼南县| 彭阳县| 印江| 肇东市| 虎林市| 沁阳市| 洛阳市| 东阳市| 永靖县| 蒲江县| 德兴市| 肥乡县| 华亭县| 宜川县| 射阳县| 临夏市| 葫芦岛市| 西畴县| 赤峰市| 英山县| 台南市| 三明市| 雅江县| 阿巴嘎旗| 赤壁市| 晴隆县| 忻城县| 连山| 达尔| 交城县| 永德县| 晴隆县| 嘉禾县|