教程android高級(jí)面試題_第1頁(yè)
教程android高級(jí)面試題_第2頁(yè)
教程android高級(jí)面試題_第3頁(yè)
教程android高級(jí)面試題_第4頁(yè)
教程android高級(jí)面試題_第5頁(yè)
已閱讀5頁(yè),還剩62頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

五、App五、App移動(dòng)端獲取網(wǎng)絡(luò)數(shù)據(jù)優(yōu)化的幾1、連接復(fù)用:節(jié)省連接建立時(shí)間,如開啟kepive。于1、連接復(fù)用:節(jié)省連接建立時(shí)間,如開啟kepive。于Anrd來(lái)說(shuō)默認(rèn)情況下nt都開啟了2響連接池的。2、請(qǐng)求合并:即將多個(gè)請(qǐng)求合并為一個(gè)進(jìn)行請(qǐng)求,比較常見的就是網(wǎng)頁(yè)中的CSSImageSprites。如3、減少請(qǐng)求數(shù)據(jù)的大?。簩?duì)于ost請(qǐng)求,body可以做ip壓縮的,header也可以做數(shù)據(jù)壓縮(不過(guò)只支持ttp2.0)。返回?cái)?shù)據(jù)的oy也可以做zp壓縮,body數(shù)據(jù)體積可以縮小到原來(lái)的30%左右(也可以考慮壓縮返回的json數(shù)據(jù)的y數(shù)據(jù)的體積,尤其是針對(duì)返回?cái)?shù)據(jù)格式變化不大的情況,支付寶聊天返回的數(shù)據(jù)用到了)。4、根據(jù)用戶的當(dāng)前的網(wǎng)絡(luò)質(zhì)量來(lái)判斷下載什么質(zhì)量的圖片(電商用的比較多)5、使用HttpDNS優(yōu)化DNS:DNS存在解析慢和DNS劫持等問(wèn)題,DNS不僅支持UDP,它還支持TCP,但是大部分標(biāo)準(zhǔn)的DNS都是基于UDPDNS服務(wù)器的53端口進(jìn)行交互。HTTPDNS則不同,顧名思義它是利用HTTP協(xié)議與DNS服務(wù)器的80端口進(jìn)行交互。不走傳統(tǒng)的DNS解析,從而繞過(guò)運(yùn)營(yíng)商的LocalDNS服務(wù)器,有效的防止了域名劫持,提高域名解析的效率。參考文客戶端網(wǎng)絡(luò)安全實(shí)七、安卓的安全這是因?yàn)樵诳蛻舳酥?,加載5頁(yè)面之前,需要先初始化bViw,在bViw加載WebView的同時(shí),請(qǐng)求H5頁(yè)面數(shù)據(jù)因此常見的方法是全局WebView客戶端代理頁(yè)面請(qǐng)求。WebView初始化完成全局WebView客戶端代理頁(yè)面請(qǐng)求。WebView初始化完成后向客戶端請(qǐng)求數(shù)asset存放離線包除此之外還有一些其他的優(yōu)化手腳本執(zhí)行慢,可以讓腳本最后運(yùn)行,不阻塞頁(yè)面解DNS鏈接慢,可以讓客戶端復(fù)用使用的域名與鏈React框架代碼執(zhí)行慢,可以將這部分代碼拆分出來(lái),提前進(jìn)行解為了加速你的viw,對(duì)于頻繁調(diào)用的方法,需要盡量減少不必要的代碼。先從onDaw開始,需要特別注意不應(yīng)該在這里做內(nèi)存分配的事情,因?yàn)樗鼤?huì)導(dǎo)致GC,從而導(dǎo)致卡頓。在初始化或者動(dòng)畫間隙期間做分配內(nèi)存的動(dòng)作。不要在動(dòng)畫正在執(zhí)行的時(shí)候做內(nèi)存分配的事情。你還需要盡可能的減少onDaw被調(diào)用的次數(shù),大多數(shù)時(shí)候?qū)е耾nDaw都是因?yàn)檎{(diào)用了ad().因此請(qǐng)盡量減少調(diào)用nvaiat()的次數(shù)。如果可能的話,盡量調(diào)用含有4個(gè)參數(shù)的iade()iviate()。沒(méi)有參數(shù)的invalate會(huì)強(qiáng)制重繪整個(gè)viw。另外一個(gè)非常耗時(shí)的操作是請(qǐng)求ayot。任何時(shí)候執(zhí)行yut(),會(huì)使得nddUI系統(tǒng)去遍歷整個(gè)iw的層級(jí)來(lái)計(jì)算出每一個(gè)viw的大小。如果找到有沖突的值,它會(huì)需要重新計(jì)算好幾次。另外需要盡量保持iw的層級(jí)是扁平化的,這樣對(duì)提高效率很有幫助。如果你有一個(gè)復(fù)雜的UI,你應(yīng)該考慮寫一個(gè)自定義的iwp來(lái)執(zhí)行他的ayot操作。與內(nèi)置的viw不同,自定義的viw可以使得程序僅僅測(cè)量這一部分,這避免了遍歷整個(gè)viw4、Close)什么Error、OOM,StackOverFlowError、Runtime,比如說(shuō)空指針異解決的辦法注意內(nèi)存的使用和管使用Thread.UncaughtExceptionHandler接5、Java多線程引發(fā)的性能問(wèn)題,怎么解決二、Framework相Android是一種基于Linux的開放源代碼軟件棧,為廣泛的設(shè)備和機(jī)型而創(chuàng)建。下圖所示為Android平1.應(yīng)用程Android隨附一套用于電子郵件、短信、日歷、互聯(lián)網(wǎng)瀏覽和聯(lián)系人等的核心應(yīng)用。平臺(tái)隨附的應(yīng)用與Messenger甚至默認(rèn)鍵盤(有一些例外,例如系統(tǒng)的“設(shè)置”應(yīng)用)。系統(tǒng)應(yīng)用可用作用戶的應(yīng)用,以及提供開發(fā)者可從其自己的應(yīng)用訪問(wèn)的主要功能。例如,如果您的應(yīng)用要發(fā)短信,您無(wú)需自己構(gòu)建該功能,可以改為調(diào)用已安裝的短信應(yīng)用向您指定的接收者發(fā)送消息。2、JavaAPI框您可通過(guò)以Java語(yǔ)言編寫的您可通過(guò)以Java語(yǔ)言編寫的APIAndroidOS的整個(gè)功能集。這些API形成創(chuàng)建Android應(yīng)用所豐富、可擴(kuò)展的視圖系統(tǒng),可用以構(gòu)建應(yīng)用的UI,包括列表、網(wǎng)格、文本框、按鈕甚至可嵌入的Activity管理器,用于管理應(yīng)用的生命周期,提供常見的導(dǎo)航返內(nèi)容提供程序,可讓應(yīng)用訪問(wèn)其他應(yīng)用(例如“聯(lián)系人”應(yīng)用)中的數(shù)據(jù)或者共享其自己的開發(fā)者可以完全訪問(wèn)Android系統(tǒng)應(yīng)用使用的框架API3、系統(tǒng)運(yùn)原生C/C+許多核心Android系統(tǒng)組件和服務(wù)(例如ARTHAL)構(gòu)建自原生代碼,需要以CC++編寫的原生庫(kù)。Android平臺(tái)提供Java框架API以向應(yīng)用顯示其中部分原生庫(kù)的功能。例如,您可以通過(guò)Android框架的JavaOpenGLAPI訪問(wèn)OpenGLES,以支持在應(yīng)用中繪制和操作2D3D圖形。如果開發(fā)的是需要C或C++代碼的應(yīng)用,可以使用AndroidNDK直接從原生代碼訪問(wèn)某些原生平臺(tái)庫(kù)。Android對(duì)于運(yùn)行Android5.0(API級(jí)別21)或更高版本的設(shè)備,每個(gè)應(yīng)用都在其自己的進(jìn)程中運(yùn)行,并且有其自己的AndroidRuntime(ART)實(shí)例。ART編寫為通過(guò)執(zhí)行DEX文件在低內(nèi)存設(shè)備上運(yùn)行多個(gè)虛擬機(jī),DEX文件是一種專為Android設(shè)計(jì)的字節(jié)碼格式,經(jīng)過(guò)優(yōu)化,使用的內(nèi)存很少。編譯工具鏈(例如Jack)將Java源代碼編譯為DEX字節(jié)碼,使其可在Android平臺(tái)上運(yùn)行。ART的部分主要功能包括優(yōu)化的垃圾回收(GC)更好的調(diào)試支持,包括專用采樣分析器、詳細(xì)的診斷異常和崩潰報(bào)告,并且能夠設(shè)置監(jiān)視點(diǎn)以監(jiān)控特定字段在Android版本5.0(API級(jí)別21)之前,Dalvik是AndroidRuntime。如果您的應(yīng)用在ART上運(yùn)行效果很好,那么它應(yīng)該也可在Dalvik上運(yùn)行,但反過(guò)來(lái)不一定。Android還包含一套核心運(yùn)行時(shí)庫(kù),可提供JavaAPI框架使用的Java編程語(yǔ)言大部分功能,包括Java8語(yǔ)言功能4、硬件抽象層硬件抽象層(HAL)提供標(biāo)準(zhǔn)界面,向更高級(jí)別的JavaAPI框架顯示設(shè)備硬件功能。HAL包含多個(gè)庫(kù)模塊,其中每個(gè)模塊都為特定類型的硬件組件實(shí)現(xiàn)一個(gè)界面,例如相機(jī)或藍(lán)牙模塊。當(dāng)框架API要求訪問(wèn)設(shè)備硬件時(shí),Android系統(tǒng)將為該硬件組件加載庫(kù)模塊。5、LinuxAndroid平臺(tái)的基礎(chǔ)Linux內(nèi)核。例如,AndroidRuntimeART)Linux內(nèi)核來(lái)執(zhí)行底層功能,例如線程和低層內(nèi)存管理。使用Linux內(nèi)核可讓Android利用主要安全功能,并且允許設(shè)備制造商為著對(duì)于Android了解Activity的構(gòu)觸摸事件對(duì)應(yīng)的是MotionEvent類,事件的類型主要有如下三ACTION_MOVE(移動(dòng)的距離超過(guò)一定的閾值會(huì)被判定ACTION_MOVE(移動(dòng)的距離超過(guò)一定的閾值會(huì)被判定為ACTION_MOVE操作w事件分發(fā)本質(zhì)就是對(duì)MotionEvent事件分發(fā)的過(guò)程。即當(dāng)一個(gè)MotionEventiw上。事件分發(fā)過(guò)程由三個(gè)方法共同完t方法進(jìn)行ensuper.otrceptTouchEv(),事件攔截分兩種情況:如果該View存在子View且點(diǎn)擊到了該子View則不攔截繼續(xù)分發(fā)給子View處理,此時(shí)相當(dāng)于returnfalse。如果該View沒(méi)有子View或者有子View但是沒(méi)有點(diǎn)擊中子View(此時(shí)相當(dāng)于普通View),則交由該View的onTouchEvent響應(yīng),此時(shí)相當(dāng)于returntrue注意:一般的LinearLayout ScrollView、ListView等ViewGroup則可能攔截,得看具體情onhvnt:方法返回值為true表示當(dāng)前視圖可以處理對(duì)應(yīng)的事件;返回值為flseonchvent方法進(jìn)行處理。如果rnsuper.onucvt(v),事件處理分為兩種情況:如果該View是clickable或者longclickable的,則會(huì)返回true,表示消費(fèi)了該事件,與返回true一樣;如果該View不是clickable或者longclickable的,則會(huì)返回false,表示不注意:在Android系統(tǒng)中,擁有事件傳遞處理能力的類有以下三三個(gè)方法的關(guān)系用偽代碼表示如publicbooleandispatchTouchEvent(MotionEvent{booleanconsume=if{consume=}elsecoonsume=}return}通過(guò)上面的偽代碼,我們可以大致了解點(diǎn)擊事件的傳遞規(guī)則:對(duì)應(yīng)一個(gè)根wopdchhvent就會(huì)被調(diào)用,如果這個(gè)Vwp的Itecthvent方法返回true就表示它要攔截當(dāng)前事件,接著事件就會(huì)交給這個(gè)Vwp處理,這時(shí)如果它的mOuchListener被設(shè)置,則onouch會(huì)被調(diào)用,否則onuchEvet會(huì)被調(diào)用。在在onhvt中,如果設(shè)置了mOnCckListr,則nck會(huì)被調(diào)用。只要w的LICKABLE和ONG_ICKABLE有一個(gè)為true,onoEve)就會(huì)返回true消耗這個(gè)事件。如果這個(gè)Vw的oIteceptvt方法返回false就表示它不攔截當(dāng)前事件,這時(shí)當(dāng)前事件就會(huì)繼續(xù)傳遞給它的子元素,接著子元素的dpchhvt方法就會(huì)被調(diào)用,如此反復(fù)直到事件被最終處理。2、正常情況下,一個(gè)時(shí)間序列只能被一個(gè)w攔截且消耗。因?yàn)橐坏┮粋€(gè)元素?cái)r截了此事件,那么同一個(gè)事件序列內(nèi)的所有事件都會(huì)直接交給它處理(即不會(huì)再調(diào)用這個(gè)w的攔截方法去詢問(wèn)它是否要攔截了,而是把剩余的OME、TION_DWN等事件直接交給它來(lái)處理)。特例:通過(guò)將重寫w的onouchEvet返回fe可強(qiáng)行將事件轉(zhuǎn)交給其他w處理。3、如果w不消耗除TIO_DWN以外的其他事件,那么這個(gè)點(diǎn)擊事件會(huì)消失,此時(shí)父元素的onhvnt并不會(huì)被調(diào)用,并且當(dāng)前iw可以持續(xù)收到后續(xù)的事件,最終這些消失的點(diǎn)擊事件會(huì)傳遞給Activty處理。4、ViewGroup默認(rèn)不攔截任何事件(返回false)6、View的enable屬性不影響onTouchEvent的默認(rèn)返回記住這個(gè)圖的傳遞順序,面試的時(shí)候能夠畫出來(lái),就很詳細(xì)了如果觸摸某個(gè)控件,但是又不是在這個(gè)控件的區(qū)域上抬起(移動(dòng)到別的地方了),就會(huì)action_cancel點(diǎn)擊事件被攔截,但是想傳到下面的View,如何操作重寫子類的requestDisallowInterceptTouchEvent()方法返回true就不會(huì)執(zhí)行父類onInterceptTouchEvent(),即可將點(diǎn)擊事件傳到下面的View如何解決View常見開發(fā)中事件沖突的有SclViw與ecycViw的滑動(dòng)沖突、RecyclerViw向?;瑒?dòng)沖突的處理規(guī)則對(duì)于由于外部滑動(dòng)和內(nèi)部滑動(dòng)方向不一致導(dǎo)致的滑動(dòng)沖突,可以根據(jù)滑動(dòng)的方向判斷誰(shuí)來(lái)攔截事件。對(duì)于由于外部滑動(dòng)方對(duì)于由于外部滑動(dòng)和內(nèi)部滑動(dòng)方向不一致導(dǎo)致的滑動(dòng)沖突,可以根據(jù)滑動(dòng)的方向判斷誰(shuí)來(lái)攔截事件。對(duì)于由于外部滑動(dòng)方向和內(nèi)部滑動(dòng)方向一致導(dǎo)致的滑動(dòng)沖突,可以根據(jù)業(yè)務(wù)需求,規(guī)定何時(shí)讓View攔截事件,何時(shí)由內(nèi)部View攔截事對(duì)于上面兩種情況的嵌套,相對(duì)復(fù)雜,可同樣根據(jù)需求在業(yè)務(wù)上找到突破滑動(dòng)沖突的實(shí)現(xiàn)方法內(nèi)部攔截法:指父容器不攔截任何事件,而將所有的事件都傳遞給子容器,如果子容器需要此事件就直接消耗,否則就交由父容器進(jìn)行處理。具體方法:需要配合qestDisallcethvent方法。加深理DecorView被加載到Window從ActtystartActivy開始,最終調(diào)用到ActtyThdhndeanchActty方法來(lái)創(chuàng)建Activy,首先,會(huì)調(diào)用performLaunchActivy方法,內(nèi)部會(huì)執(zhí)行ActivtyoCee方法,從而完成crw和Activy的創(chuàng)建。然后,會(huì)調(diào)用hdemectt,里面首先會(huì)調(diào)用rformResumecivity去執(zhí)行Activty的nRsume()方法,執(zhí)行完后會(huì)得到一個(gè)Activyitcod對(duì)象,然后通過(guò)r.wind.gtcorViw()的方式得到crw過(guò)gtWidM)得到WdwManagr,最終調(diào)用其addViw()方法將riw加進(jìn)去。繪制會(huì)從根視圖Rot的prformvrsas()方法開始,從上到下遍歷整個(gè)視圖樹,每個(gè)iw負(fù)責(zé)繪制自己,而wop還需要負(fù)責(zé)通知自己的子w進(jìn)行繪制操作。理解MeasuSec表示的是一個(gè)32位的整形值,它的高2位表示測(cè)量模式pMe,低30SecSize。MeasupcVw類的一個(gè)靜態(tài)內(nèi)部類,用來(lái)說(shuō)明應(yīng)該如何測(cè)量這個(gè)w。它由三種測(cè)量模式,如下:EXTY:精確測(cè)量模式,視圖寬高指定為match_pat或具體數(shù)值時(shí)生效,表示父視圖已經(jīng)決定了子視圖的精確大小,這種模式下Vw的測(cè)量值就是SpecSze的值。T_MOST:最大值測(cè)量模式,當(dāng)視圖的寬高指定為wntentUNSPECIFIED:不指定測(cè)量模式父視圖沒(méi)有限制子視圖的大小,子視圖可以是想要的任何尺寸,MeasuSec通過(guò)將SpMd和SpecSize打包成一個(gè)it值來(lái)避免過(guò)多的對(duì)象內(nèi)存分配,為了方便操作,其提供了打包和解包的方法,打包方法為maMeupc,解包方法為getModegetSiz。普通View的MeasureSpec的創(chuàng)建規(guī)則如對(duì)于DecorView而言,它的MeasureSpec由對(duì)于DecorView而言,它的MeasureSpec由窗口尺寸和其自身的LayoutParams共同決定;對(duì)于普通View,它的MeasureSpec由父視圖的MeasureSpec和其自身的LayoutParams共同決定View繪制流程之首先,在ViewGroup中的measureChildren()方法中會(huì)遍歷測(cè)量ViewGroup中所有的View,View的可見性處于GONE狀態(tài)時(shí),不對(duì)其進(jìn)行測(cè)然后,測(cè)量某個(gè)指定的Vw時(shí),根據(jù)父容器的MeasueSpec和子VwLtas算子w的Mupec。最后,將計(jì)算出的MeasueSpec傳入Vw的measue方法,這里iwpiwp是一個(gè)抽象類,其測(cè)量過(guò)程的onMeasue方法需要各個(gè)子類去實(shí)現(xiàn)。不同的wp子類有不同的布局特性,這導(dǎo)致它們的測(cè)量細(xì)節(jié)各不相同,如果需要自定義測(cè)量過(guò)程,則子類可以重寫這個(gè)方法。(sMeunsn方法用于設(shè)置w的測(cè)量寬高,如果w沒(méi)有重寫onMeasue方法,則會(huì)默認(rèn)調(diào)用etfuze來(lái)獲得Vw的寬高)getSuggestMinimumWidth分如果View沒(méi)有設(shè)置背景,那么返回android:minWidth這個(gè)屬性所指定的值,這個(gè)值可以為0;如View設(shè)置了背景,則返回android:minWidth和背景的最小寬度這兩者中的最大自定義View時(shí)手動(dòng)處理wrap_contentLinearLayout的onMeasure方法實(shí)現(xiàn)解析(這里僅分析measureVertical核心源碼系統(tǒng)會(huì)遍歷子元素并對(duì)每個(gè)子元素執(zhí)行measuCdBoLut方法,這個(gè)方法內(nèi)部會(huì)調(diào)用子元素的measue方法,這樣各個(gè)子元素就開始依次進(jìn)入measue過(guò)程,并且系統(tǒng)會(huì)通過(guò)motaength這個(gè)變量來(lái)存儲(chǔ)Lierayout在豎直方向的初步高度。每測(cè)量一個(gè)子元素,motaength就會(huì)增加,增加的部分主要包括了子元素的高度以及子元素在豎直方向上的mgin等。在Activity中獲取某個(gè)View的寬由于Viw的measue過(guò)程和Activy的生命周期方法不是同步執(zhí)行的,如果Vw還沒(méi)有測(cè)量完畢,那么獲得的寬/高就是0。所以在Ceate、onStart、nsme中均無(wú)法正確得到某個(gè)w的寬高信息。解決方式如下:wy的窗口得到焦點(diǎn)和失去焦點(diǎn)時(shí)均會(huì)被調(diào)用一次,如果頻繁地進(jìn)行see也會(huì)被頻繁地調(diào)用。view.post(runnable):通過(guò)post可以將一個(gè)runnable投遞到消息隊(duì)列的尾部,始化好了然后等待.meue(tihMasu.meue(tihMasupec,ithehtMeasup):match_paent時(shí)不知道ntSiz的大小,測(cè)不出;具體數(shù)值時(shí),直接maeMasupec固定值,然后調(diào)用vi..masue就可以了;wntent時(shí),在最大化模式下,用iw構(gòu)造MeasueSpec是合理的。View的繪制流程之首先,會(huì)通過(guò)setFe方法來(lái)設(shè)定w的四個(gè)頂點(diǎn)的位置,即w在父容器中的位置。然后,會(huì)執(zhí)行到Lut空方法,子類如果是Vwp類型,則重寫這個(gè)方法,實(shí)現(xiàn)Vwp中所有Vw布局流程。LinearLayout的onLayout方法實(shí)現(xiàn)解析(layoutVertical核心源碼其中會(huì)遍歷調(diào)用每個(gè)子VwstlFame方法為子元素確定對(duì)應(yīng)的位置。其中的cp注意:在Vw的默認(rèn)實(shí)現(xiàn)中,w的測(cè)量寬/高和最終寬/高是相等的,只不過(guò)測(cè)量寬/高形成于w的measue過(guò)程,而最終寬/高形成于w的yut過(guò)程,即兩者的賦值時(shí)機(jī)不同,測(cè)量寬/高的賦值時(shí)機(jī)稍微早一些。在一些特殊的情況下則兩者不相等:重寫View的layout方法,使最終寬度總是比測(cè)量寬/高大100pxw需要多次measue才能確定自己的測(cè)量寬/高,在前幾次測(cè)量的過(guò)程中,其得出的測(cè)量寬/可能和最終寬/高不一致,但最終來(lái)說(shuō),測(cè)量寬/高還是和最終寬/高相同。View的繪制流程之Draw的基本流繪制基本上可以分為六個(gè)步首先繪制View的背景接著,繪制View的子setWillNotDraw的作如果一個(gè)View不需要繪制任何內(nèi)容,那么設(shè)置這個(gè)標(biāo)記位為true以后,系統(tǒng)會(huì)進(jìn)行相應(yīng)的優(yōu)化默認(rèn)情況下,View沒(méi)有啟用這個(gè)優(yōu)化標(biāo)記位,但是ViewGroup會(huì)默認(rèn)啟用這個(gè)優(yōu)化標(biāo)記位當(dāng)我們的自定義控件繼承于wp并且本身不具備繪制功能時(shí),就可以開啟這個(gè)標(biāo)記位從而便于系統(tǒng)進(jìn)行后續(xù)的優(yōu)化。當(dāng)明確知道一個(gè)ViewGroup需要通過(guò)onDraw來(lái)繪制內(nèi)容時(shí),我們需要顯示地WILL_NOT_DRAW這個(gè)標(biāo)記位Requestlayout,onlayout,onDraw,DrawChild區(qū)別與聯(lián)requestLayout()方法會(huì)導(dǎo)致調(diào)用measure()過(guò)程layout()過(guò)程,將會(huì)根據(jù)標(biāo)志位判斷是否需要onLayout()方法:如果該View是ViewGroup對(duì)象,需要實(shí)現(xiàn)該方法,對(duì)每個(gè)子視圖進(jìn)行布局onDraw()方法:繪制視圖本身(每個(gè)View都需要重載該方法,ViewGroup不需要實(shí)現(xiàn)該方法)drawChild():去重新回調(diào)每個(gè)子視圖的draw()方法invalidate()postInvalidate()的區(qū)別vle()與ostIvle()與ostInvadt()都用于刷新w,主要區(qū)別是nvalt()hnlr;而ostIalde()可在子線程中直接調(diào)用。更詳細(xì)的內(nèi)容請(qǐng)點(diǎn)擊這Android中進(jìn)程和線程的關(guān)系?區(qū)別線程是CPU調(diào)度的最小單元,同時(shí)線程是一種有限的系統(tǒng)資源;而進(jìn)程一般指一個(gè)執(zhí)行單元PC和移動(dòng)設(shè)備上指一個(gè)程序或者一個(gè)應(yīng)一般來(lái)說(shuō),一個(gè)App程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程(包含與被包含的關(guān)系),通俗來(lái)講就是,在App這個(gè)工廠里面有一個(gè)進(jìn)程,線程就是里面的生產(chǎn)線,但主線程(即主生產(chǎn)線)只有一條,而子線程(即副生產(chǎn)線)可以有多個(gè)。進(jìn)程有自己獨(dú)立的地址空間,而進(jìn)程中的線程共享此地址空間,都可以并發(fā)執(zhí)如何開啟多進(jìn)程?應(yīng)用是否可以開啟N個(gè)進(jìn)程ts個(gè)進(jìn)程。所有運(yùn)行在不同進(jìn)程的四大組件(Activy、ServeRciverntentver)共享數(shù)據(jù)都會(huì)失敗,這是由于dod為每個(gè)應(yīng)用分配了獨(dú)立的虛擬機(jī),不同的虛擬機(jī)在內(nèi)存分配上有不同的地址空間,這會(huì)導(dǎo)致在不同的虛擬機(jī)中訪問(wèn)同一個(gè)類的對(duì)象會(huì)產(chǎn)生多份副本。比如常用例子()。一般來(lái)說(shuō),使用多進(jìn)程通信會(huì)造成如下幾方面的問(wèn)題Shedencs的可靠性下降:這是因?yàn)镾p不支持兩個(gè)進(jìn)程并發(fā)進(jìn)行讀寫,有一定幾率導(dǎo)致數(shù)據(jù)丟失。Applation會(huì)多次創(chuàng)建:Andd系統(tǒng)在創(chuàng)建新的進(jìn)程時(shí)會(huì)分配獨(dú)立的虛擬機(jī),所以這個(gè)過(guò)程其實(shí)就是啟動(dòng)一個(gè)應(yīng)用的過(guò)程,自然也會(huì)創(chuàng)建新的Appication。Android中IPC方式、各種方式優(yōu)缺點(diǎn)AIL(AndidInterfacee?nitinLuAIL(AndidInterfacee?nitinLue,dod接口定義語(yǔ)言):如果在一個(gè)進(jìn)程中要調(diào)用另一個(gè)進(jìn)程中對(duì)象的方法,可使用AIL生成可序列化的參數(shù),AIL會(huì)生成一個(gè)服務(wù)端對(duì)象的代理類,通過(guò)它客戶端可以實(shí)現(xiàn)間接調(diào)用服務(wù)端對(duì)象的方法。Stub類:Binder的實(shí)現(xiàn)類,服務(wù)端通過(guò)這個(gè)類來(lái)提供服Proxy類:服務(wù)端的本地代理,客戶端通過(guò)這個(gè)類調(diào)用服務(wù)端客戶端調(diào)用,將服務(wù)端返回的Bder對(duì)象,轉(zhuǎn)換成客戶端所需要的AIL接口類型的對(duì)象。如果客戶端和服務(wù)端位于同一進(jìn)程,則直接返回tubStpxy對(duì)象。asBinder():根據(jù)當(dāng)前調(diào)用情況返回代理Proxy的Binder對(duì)象運(yùn)行在服務(wù)端的Binder線程池中,當(dāng)客戶端發(fā)起跨進(jìn)程請(qǐng)求時(shí),遠(yuǎn)程請(qǐng)求會(huì)通過(guò)系統(tǒng)底層由此方法來(lái)處理transact():運(yùn)行在端,當(dāng)客戶端發(fā)起遠(yuǎn)程請(qǐng)求的同時(shí)將當(dāng)前線程掛起。之后調(diào)用服務(wù)端的onTransact()直到遠(yuǎn)程請(qǐng)求當(dāng)有多個(gè)業(yè)務(wù)模塊都需要AIL來(lái)進(jìn)行IPC,此時(shí)需要為每個(gè)模塊創(chuàng)建特定的al文件,那么相應(yīng)的Serve就會(huì)很多。必然會(huì)出現(xiàn)系統(tǒng)資源耗費(fèi)嚴(yán)重、應(yīng)用過(guò)度重量級(jí)的問(wèn)題。解決辦法是建立Binder連接池,即將每個(gè)業(yè)務(wù)模塊的Bnder請(qǐng)求統(tǒng)一轉(zhuǎn)發(fā)到一個(gè)遠(yuǎn)程Serve中去執(zhí)行,從而避免重復(fù)創(chuàng)建Serve。工作原理:每個(gè)業(yè)務(wù)模塊創(chuàng)建自己的AIL接口并實(shí)現(xiàn)此接口,然后向服務(wù)端提供自己的唯一標(biāo)識(shí)和其對(duì)應(yīng)的Binder對(duì)象。服務(wù)端只需要一個(gè)Service并提供一個(gè)urydr接口,它會(huì)根據(jù)業(yè)務(wù)模塊的特征來(lái)返回相應(yīng)的Binder對(duì)象,不同的業(yè)務(wù)模塊拿到所需的Binder對(duì)象后就可以進(jìn)行遠(yuǎn)程方法的調(diào)用了。為什么選擇為什么選用Binder,在討論這個(gè)問(wèn)題之前,我們知道Andd也是基于nx內(nèi)核,nx管道:在創(chuàng)建時(shí)分配一個(gè)page大小的內(nèi)存,緩存區(qū)大小比較有消息隊(duì)列:信息復(fù)制兩次,額外的CPU消耗;不合適頻繁或信息量大的通共享內(nèi)存:無(wú)須復(fù)制,共享緩沖區(qū)直接附加到進(jìn)程虛擬地址空間,速度快;但進(jìn)程間的同步問(wèn)題操作系統(tǒng)無(wú)法實(shí)現(xiàn),必須各進(jìn)程利用同步工具解決;套接字:作為更通用的接口,傳輸效率低,主要用于不同機(jī)器或跨網(wǎng)絡(luò)的通信號(hào)量:常作為一種鎖機(jī)制,防止某進(jìn)程正在訪問(wèn)共享資源時(shí),其他進(jìn)程也訪問(wèn)該資源。因此,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段。不適用于信息交換,更適用于進(jìn)程中斷控制,比如非法內(nèi)存訪問(wèn),殺死某個(gè)進(jìn)程等;既然有現(xiàn)有的IPC方式,為什么重新設(shè)計(jì)一套Binder機(jī)制呢。主要是出于以上三個(gè)方面的考1、效率:傳輸效率主要影響因素是內(nèi)存拷貝的次數(shù),拷貝次數(shù)越少,傳輸速率越高。從d進(jìn)程架構(gòu)角度分析:對(duì)于消息隊(duì)列、Soct和管道來(lái)說(shuō),數(shù)據(jù)先從發(fā)送方的緩存區(qū)拷貝到內(nèi)核開辟的緩存區(qū)中,再?gòu)膬?nèi)核緩存區(qū)拷貝到接收方的緩存區(qū),一共兩次拷貝,如圖:而對(duì)于Bder而對(duì)于Bder來(lái)說(shuō),數(shù)據(jù)從發(fā)送方的緩存區(qū)拷貝到內(nèi)核的緩存區(qū),而接收方的緩存區(qū)與內(nèi)核的緩存區(qū)是映射到同一塊物理地址的,節(jié)省了一次數(shù)據(jù)拷貝的過(guò)程,如圖:共享內(nèi)存不需要拷貝,Binder的性能僅次于共享內(nèi)存2、穩(wěn)定性:上面說(shuō)到共享內(nèi)存的性能優(yōu)于Bder,那為什么不采用共享內(nèi)存呢,因?yàn)楣蚕韮?nèi)存需要處理并發(fā)同步問(wèn)題,容易出現(xiàn)死鎖和資源競(jìng)爭(zhēng),穩(wěn)定性較差。Sct雖然是基于S架構(gòu)的,但是它主要是用于網(wǎng)絡(luò)間的通信且傳輸效率較低。Bder基于C/S架構(gòu),Servr端與lt端相對(duì)獨(dú)立,穩(wěn)定性較好。3、安全性:傳統(tǒng)LinuxIPC的接收方無(wú)法獲得對(duì)方進(jìn)程可靠的UID/PID,從而無(wú)法鑒別對(duì)方身份;Binder機(jī)制的作用和原理Linux系統(tǒng)將一個(gè)進(jìn)程分為用戶空間和內(nèi)核空間。對(duì)于進(jìn)程之間來(lái)說(shuō),用戶空間的數(shù)據(jù)不可共享,內(nèi)核空間的數(shù)據(jù)可共享,為了保證安全性和獨(dú)立性,一個(gè)進(jìn)程不能直接操作或者訪問(wèn)另一個(gè)進(jìn)程,即dod的進(jìn)程是相互獨(dú)立、隔離的,這就需要跨進(jìn)程之間的數(shù)據(jù)通信方式。普通的跨進(jìn)程通信方式一般需要2次內(nèi)存拷貝,如下圖所示:一次完整的Binder一次完整的BinderIPC通信過(guò)程通常是這樣首先Binder驅(qū)動(dòng)在內(nèi)核空間創(chuàng)建一個(gè)數(shù)據(jù)接收緩存接著在內(nèi)核空間開辟一塊內(nèi)核緩存區(qū),建立內(nèi)核緩存區(qū)和內(nèi)核中數(shù)據(jù)接收緩存區(qū)之間的映射關(guān)系,以及內(nèi)核中數(shù)據(jù)接收緩存區(qū)和接收進(jìn)程用戶空間地址的映射關(guān)系。發(fā)送方進(jìn)程通過(guò)系統(tǒng)調(diào)用coymr()將數(shù)據(jù)coy到內(nèi)核中的內(nèi)核緩存區(qū),由于內(nèi)核緩存區(qū)和接收進(jìn)程的用戶空間存在內(nèi)存映射,因此也就相當(dāng)于把數(shù)據(jù)發(fā)送到了接收進(jìn)程的用戶空間,這樣便完成了一次進(jìn)程間的通信。Binder框架中ServiceManager的作用Binder框架是基于C/S架構(gòu)的Binder框架是基于C/S架構(gòu)的。由一系列的組件組成,包括Client、Server、ServiceManager、Server&Client:服務(wù)器&客戶端。在Binder驅(qū)動(dòng)和ServiceManager提供的基礎(chǔ)設(shè)施上,進(jìn)行Bnder驅(qū)動(dòng)(如同路由器):負(fù)責(zé)進(jìn)程之間bnr通信的建立,計(jì)數(shù)管理以及數(shù)據(jù)的傳遞交互等底層支持。最后,結(jié)合Android跨進(jìn)程通信:圖文詳解Binder機(jī)制的總結(jié)圖來(lái)綜合理解一Binder的完整定從進(jìn)程Binder的完整定從進(jìn)程間通信的角度看,Binder是一種進(jìn)程間通信的機(jī)制從Server進(jìn)程的角度看,Binder指的是Server中的Binder實(shí)體對(duì)象從Clt進(jìn)程的角度看,Binder指的是Bnder代理對(duì)象,是Bnder實(shí)體對(duì)象的一個(gè)遠(yuǎn)程代理;從傳輸過(guò)程的角度看,Bder是一個(gè)可以跨進(jìn)程傳輸?shù)膶?duì)象;Bder手寫實(shí)現(xiàn)簡(jiǎn)化版AMS(AIDL實(shí)現(xiàn)與Binder相關(guān)的幾個(gè)類的職責(zé)IBinder:跨進(jìn)程通信的Base接口,它聲明了跨進(jìn)程通信需要實(shí)現(xiàn)的一系列抽象方法,實(shí)現(xiàn)了這個(gè)接口就說(shuō)明可以進(jìn)行跨進(jìn)程通信,Clt和Server都要實(shí)現(xiàn)此接口。Itace:這也是一個(gè)Base接口,用來(lái)表示Servr提供了哪些能力,是Cet和vr議。Bnder:提供Bnder服務(wù)的本地對(duì)象的基類,它實(shí)現(xiàn)了IBnder類。a類,這個(gè)類表示代理對(duì)象它同樣實(shí)現(xiàn)了IBinder接口,不過(guò)它的很多實(shí)現(xiàn)都交由e層處理。t中拿到的實(shí)際上是這個(gè)代理對(duì)象tub:這個(gè)類在編譯al個(gè)代理對(duì)象tub:這個(gè)類在編譯al文件后自動(dòng)生成,它繼承自Binder,表示它是一個(gè)BderIInterface接口,表明它的子類需要實(shí)現(xiàn)Servr將要提供的具體能力(即al文件中聲明的方法)。xy:它實(shí)現(xiàn)了IInterface接口,說(shuō)明它是Bder通信過(guò)程的一部分;它實(shí)現(xiàn)了l中聲明的方法,但最終還是交由其中的meme成員來(lái)處理,說(shuō)明它是一個(gè)代理對(duì)象,meme上就是Binrxy。l文件只是用來(lái)定義/S交互的接口,dod在編譯時(shí)會(huì)自動(dòng)生成相應(yīng)的Java類,生成的類中包含了tub和Pxy靜態(tài)內(nèi)部類,用來(lái)封裝數(shù)據(jù)轉(zhuǎn)換的過(guò)程,實(shí)際使用時(shí)只關(guān)心具體的Java接口類即可。為什么tub和xy是靜態(tài)內(nèi)部類呢?這其實(shí)只是為了將三個(gè)類放在一個(gè)文件中,提高代碼的聚合性。通過(guò)上面的分析,我們其實(shí)完全可以不通過(guò)aidl,手動(dòng)編碼來(lái)實(shí)現(xiàn)Bnder的通信,下面我們通過(guò)編碼來(lái)實(shí)現(xiàn)ActivyMaarService:1、首先定義IActivityManager接口2、然后,實(shí)現(xiàn)ActivityManagerService側(cè)的本地Binder對(duì)象基類//名稱隨意,不一定叫IActivityManager{publicstaticIActivityManagerasInterface(IBinder{if(obj==null){returnnull;}IActivityManagerin=(IActivityManager)if(in!={return}returnnew}publicIBinder{return}protectedbooleanonTransact(intcode,Parceldata,ParcelthrowsRemoteException{switch(code)//獲取binderintpublicinterfaceIActivityManagerextendsIInterfaceStringDESCRIPTOR=intTRANSACTION_startActivity=IBinder.FIRST_CALL_TRANSACTION+}casereturntrue;//casereturntrue;//啟動(dòng)activity,從data中反序列化出intent參數(shù)后,直接調(diào)用子類caseIActivityManager.TRANSACTION_startActivity:intresult=this.startActivity(intent);returntrue;}returnsuper.onTransact(code,data,reply,}}3、接著,實(shí)現(xiàn)Client側(cè)的代理對(duì)象4、最后,實(shí)現(xiàn)Binder本地對(duì)象(IActivityManager接口privateIBindermRemote;publicActivityManagerProxy(IBinder{mRemote=}publicIBinderasBinder(){returnmRemote;}publicintstartActivity(Intentintent)throwsRemoteException{Parceldata=Parcel.obtain();Parcelreply=Parcel.obtain();intresult;try//將intent參數(shù)序列化,寫入dataintent.writeToParcel(data,//調(diào)用BinderProxy對(duì)象的transact方法,交由Binder reply,//等待serverresult=}finally}return}}簡(jiǎn)化版的ActivityManagerService到這里就已經(jīng)簡(jiǎn)化版的ActivityManagerService到這里就已經(jīng)實(shí)現(xiàn)了,剩下就是Client只需要獲取到AMS的代理IActivityManager就可以通信了寫給Android應(yīng)用工程師的Binder原理剖析老羅Binder機(jī)制分析系列或Android系統(tǒng)源代碼情景分析Binder章5、Android系統(tǒng)啟動(dòng)流程是什么?(提示:init進(jìn)程->ZygoteSystemServer應(yīng)用進(jìn)程Android系統(tǒng)啟動(dòng)的核心流程如1啟動(dòng)電源以及系統(tǒng)啟動(dòng):當(dāng)電源按下時(shí)引導(dǎo)芯片從預(yù)定義的地方(固化在ROM)載引導(dǎo)程序Boer到M,然后執(zhí)行。2引導(dǎo)程序BootLoader:otLoader是在Andid系統(tǒng)開始運(yùn)行前的一個(gè)小程序,主要用于把系統(tǒng)OS拉起來(lái)并運(yùn)行。3Linux內(nèi)核啟動(dòng):當(dāng)內(nèi)核啟動(dòng)時(shí),設(shè)置緩存、被保護(hù)存儲(chǔ)器、計(jì)劃列表、加載驅(qū)動(dòng)。當(dāng)其完成系統(tǒng)設(shè)置時(shí),會(huì)先在系統(tǒng)文件中尋找it.c文件,并啟動(dòng)t進(jìn)程。4、init進(jìn)程啟動(dòng):初始化和啟動(dòng)屬性服務(wù),并且啟動(dòng)Zygote進(jìn)程5Zygote進(jìn)程啟動(dòng):創(chuàng)建JVM并為其注冊(cè)JI方法,創(chuàng)建服務(wù)器端Soct,啟動(dòng)Systemvr進(jìn)程。6SystemServer進(jìn)程啟動(dòng):?jiǎn)?dòng)Binder線程池和SystemveManagr服務(wù)。7Launer啟動(dòng):被Systvr進(jìn)程啟動(dòng)的AMS會(huì)啟動(dòng)anceranchr是因?yàn)閱?dòng)程序(主界面也是一個(gè)app),發(fā)現(xiàn)了在這個(gè)程序中存在一個(gè)設(shè)置為的所以這個(gè)launcher會(huì)把icon提出來(lái),放在主界面上。當(dāng)用戶點(diǎn)擊icon的時(shí)候,發(fā)出一個(gè)publicclassActivityManagerServiceextends{publicintstartActivity(Intentintent)throwsRemoteExceptionreturn0;}}跳過(guò)去可以跳到任意允許的頁(yè)面,如一個(gè)程序可以下載,那么真正下載的頁(yè)面可能不是首頁(yè)()跳過(guò)去可以跳到任意允許的頁(yè)面,如一個(gè)程序可以下載,那么真正下載的頁(yè)面可能不是首頁(yè)(),這時(shí)還是構(gòu)造一個(gè)Itt,startActivy。這個(gè)ntent中的action可能有多種viw,ad都有可能。系統(tǒng)會(huì)根據(jù)第三方程序向系統(tǒng)注冊(cè)的功能,為你的Itet選擇可以打開的程序或者頁(yè)面。所以唯一的一點(diǎn)不同的是從cn的點(diǎn)擊啟動(dòng)的ntentactn是相對(duì)單一的,從程序中跳轉(zhuǎn)或者啟動(dòng)可能樣式更多一些。本質(zhì)是相同的。7、AMSActivityManagerServices,簡(jiǎn)稱AMS,服務(wù)端對(duì)象,負(fù)責(zé)系統(tǒng)中所有Activity的生命周期ActivyThad,App的真正入口。當(dāng)開啟App之后,調(diào)用m)是傳說(shuō)的UI線程或者叫主線程。與ActivityManerServce一起完成Activy的管理工作。之間的交互。在en的生命周期時(shí),通過(guò)d的代理對(duì)象與Instrumtn,每一個(gè)應(yīng)用程序只有一個(gè)Imetain對(duì)象,每個(gè)Ativity內(nèi)都有一個(gè)對(duì)該對(duì)象的引用,Instrntation可以理解為應(yīng)用進(jìn)程的管家,ActtyThd要?jiǎng)?chuàng)建或暫停某個(gè)Activty時(shí),都需要通過(guò)Insrntation來(lái)進(jìn)行具體的操作。點(diǎn)擊應(yīng)用圖標(biāo)后會(huì)去啟動(dòng)應(yīng)用的ancherActivity,如果urActivtyActivty的啟動(dòng)流程。Activity的啟動(dòng)流程圖(放大可查看)如下所Intentintent=整個(gè)流程涉及的主要角色I(xiàn)nstrumentation:監(jiān)控應(yīng)用與整個(gè)流程涉及的主要角色I(xiàn)nstrumentation:監(jiān)控應(yīng)用與系統(tǒng)相關(guān)的交互行為AMS:組件管理調(diào)度中心,什么都不干,但是什么都ActivityStarter:Activity啟動(dòng)的控制器,處理Intent與Flag對(duì)Activity啟動(dòng)的影響,具體說(shuō)來(lái)有尋找符合啟動(dòng)條件的Activity,如果有多個(gè),讓用戶選擇;2校驗(yàn)啟動(dòng)參數(shù)的合法性;3返回int數(shù),代表Activity是否啟動(dòng)成功這個(gè)類的作用你從它的名字就可以看出來(lái),它用來(lái)管理任務(wù)棧。ActivityStack:用來(lái)管理任務(wù)棧ActivyThad:最終干活的人,Activy、Serve、astRcr注:這里單獨(dú)提一下Activytackpisior,這是高版本才有的類,它用來(lái)管理多個(gè),早期的版本只有一個(gè)Activtytack對(duì)應(yīng)著手機(jī)屏幕,后來(lái)高版本支持多屏以后,就有了多個(gè)ctivtytk,于是就引入了ctytackpsr用來(lái)管理多個(gè)ctivtytk。整個(gè)流程主要涉及四個(gè)進(jìn)調(diào)用者進(jìn)程,如果是在桌面啟動(dòng)應(yīng)用就是Launcher應(yīng)用進(jìn)程ActivityManagerService等待所在的SystemServer進(jìn)程,該進(jìn)程主要運(yùn)行著系統(tǒng)服務(wù)組件。新啟動(dòng)的應(yīng)用進(jìn)程,該進(jìn)程就是用來(lái)承載應(yīng)用運(yùn)行的進(jìn)程了,它也是應(yīng)用的主線程(就是主線程),處理組件生命周期、界面繪制等相關(guān)事情。有了以上的理解,整個(gè)流程可以概括如ry)的請(qǐng)求以的方式發(fā)。接收到啟動(dòng)請(qǐng)求后,交付rg等信息,然后再交給Ak進(jìn)棧相關(guān)流程。同時(shí)以tek3、Zygote接收到新進(jìn)程創(chuàng)建請(qǐng)求后fork出新進(jìn)程最后,再看看另一幅啟動(dòng)流程圖來(lái)加深理繼承BroadcastReceiver,重寫onReceive()方法r注冊(cè)廣播。r發(fā)送廣播。WindwManWindwManer的實(shí)現(xiàn)是WindanagerImpl,其再委托WindMngrGlbl來(lái)對(duì)Wndw進(jìn)行操作,其中有四種st分別儲(chǔ)存對(duì)應(yīng)的w、VootImpl、WindManer.LayoutPas和正在被刪除的w。Windw的實(shí)體是存在于遠(yuǎn)端的WdwManrSice,所以增刪改Wdw個(gè)st然后通過(guò)wootImpl重繪Vw,通過(guò)Wdssin(每Windw個(gè)對(duì)應(yīng)一個(gè))在遠(yuǎn)端修改Windw。APK的安裝流程如下所復(fù)制APK到/data/app目錄下,解壓并掃描安裝包資源管理器解析APK里的資源文件/目錄下創(chuàng)建對(duì)應(yīng)的應(yīng)用數(shù)據(jù)目錄。x文件進(jìn)行優(yōu)化,并保存在e將dMat文件解析出的四大組件信息注冊(cè)到PackaeMangrSrvice安裝完成后,發(fā)送廣播。15、Android的打包流程?(即描述清點(diǎn)擊Android的build按鈕后發(fā)生了什么?)apkddod的包文件APK分為兩個(gè)部分:代碼和資源,所以打包方面也分為資源打包和代碼打包兩個(gè)方面,下面就來(lái)分析資源和代碼的編譯打包原理。APK整體的的打包流程如下圖所具體說(shuō)來(lái)通過(guò)AAPT工具進(jìn)行資源文件(包括AndMnfest.xml、布局文件、各種xml資源等)生成java文件。通過(guò)AIDL工具處理AIDL文件,生成相應(yīng)的Java文件通過(guò)JavaCompiler通過(guò)AIDL工具處理AIDL文件,生成相應(yīng)的Java文件通過(guò)JavaCompiler編譯R.java、Java接口文件、Java源文件,生成.class文件通過(guò)dx命令,將.class文件和第三方庫(kù)中的.class文件處理生成classs.d,該過(guò)程主要完成字節(jié)碼轉(zhuǎn)換成k字節(jié)碼,壓縮常量池以及清除冗余信息等工作。通過(guò)Apkdr工具將資源文件、DEX文件打包生成APK文件。通過(guò)Jarsger工具,利用KyStoe對(duì)生成的APK如果是正式版的APK,還會(huì)利用ZpAlign工具進(jìn)行對(duì)齊處理,對(duì)齊的過(guò)程就是將APK文件中所有的資源文件距離文件的起始距位置都偏移4字節(jié)的整數(shù)倍,這樣通過(guò)內(nèi)存映射訪問(wèn)APK文件的速度會(huì)更快,并且會(huì)減少其在設(shè)備上運(yùn)行時(shí)的內(nèi)存占用。apk組為什么要簽確保Apk來(lái)源的真實(shí)性確保Apk沒(méi)有被第三方篡什么是簽名在Ak中寫入一個(gè)“指紋”。指紋寫入以后,Ak中有任何修改,都會(huì)導(dǎo)致這個(gè)指紋無(wú)效,Andod安裝Ak進(jìn)行簽名校驗(yàn)時(shí)就會(huì)不通過(guò),從而保證了安全性。數(shù)字摘對(duì)一個(gè)任意長(zhǎng)度的數(shù)據(jù),通過(guò)一個(gè)ash算法計(jì)算后,都可以得到一個(gè)固定長(zhǎng)度的二進(jìn)制數(shù)據(jù),這個(gè)數(shù)據(jù)就稱為“摘要”。補(bǔ)充散列算法的基礎(chǔ)原理:將數(shù)據(jù)(如一段文字)運(yùn)算變?yōu)榱硪还潭ㄩL(zhǎng)度SHA-1:在密碼學(xué)中,SHA-1(安全散列算法1)是一種加密散列函數(shù),它接受輸入并產(chǎn)生一個(gè)位(20字節(jié))散列值,稱為消息摘要M5M5消息摘要算法(英語(yǔ):M5Message-Dtlgrtm),一種被廣泛使用的密碼散列函數(shù),可以產(chǎn)生出一個(gè)28位16字節(jié))的散列值(ashvalue),致SHA-2:名稱來(lái)自于安全散列算法2(英語(yǔ):SecureHashAlgorithm2)的縮寫,一種密碼散列函SHA-512、SHA-512/224、SHA-512/256特征唯一固定長(zhǎng)度:比較常用的Hsh算法有M5和SSHA-512、SHA-512/224、SHA-512/256特征唯一固定長(zhǎng)度:比較常用的Hsh算法有M5和S1,MD5的長(zhǎng)度是28拉,SA1的長(zhǎng)度是10不可逆性簽名和校驗(yàn)的主要過(guò)簽名就是在摘要的基礎(chǔ)上再進(jìn)行一次加密,對(duì)摘要加密后的數(shù)據(jù)就可以當(dāng)作數(shù)字簽簽名過(guò)程1、計(jì)算摘要:通過(guò)Hash算法提取出原始數(shù)據(jù)的摘2、計(jì)算簽名:再通過(guò)基于密鑰(私鑰)的非對(duì)稱加密算法對(duì)提取出的摘要進(jìn)行加密,加密后的數(shù)據(jù)就是簽名信息。3、寫入簽名:將簽名信息寫入原始數(shù)據(jù)的簽名區(qū)塊校驗(yàn)過(guò)程1、首先用同樣的Hash算法從接收到的數(shù)據(jù)中提取出摘2、解密簽名:使用發(fā)送方的公鑰對(duì)數(shù)字簽名進(jìn)行解密,解密出原始摘3、比較摘要:如果解密后的數(shù)據(jù)和提取的摘要一致,則校驗(yàn)通過(guò);如果數(shù)據(jù)被第三方篡改過(guò),解密后的數(shù)據(jù)和摘要將會(huì)不一致,則校驗(yàn)不通過(guò)。數(shù)字證如何保證公鑰的可靠性呢?答案是數(shù)字證書,數(shù)字證書是身份認(rèn)證機(jī)構(gòu)(rti?cateAuthority)的,包含了以下信息:證書頒發(fā)機(jī)證書頒發(fā)機(jī)構(gòu)簽接收方收到消息后,先向CA驗(yàn)證證書的合法性,再進(jìn)行簽名校注意:Ak的證書通常是自簽名的,也就是由開發(fā)者自己制作,沒(méi)有向CA機(jī)構(gòu)申請(qǐng)。dod在安裝Apk時(shí)并沒(méi)有校驗(yàn)證書本身的合法性,只是從證書中提取公鑰和加密算法,這也正是對(duì)第三方Apk簽名后,還能夠繼續(xù)在沒(méi)有安裝這個(gè)Apk的系統(tǒng)中繼續(xù)安裝的原因。keystore和證書格ytoe文件中包含了私鑰、公鑰和數(shù)字證書。根據(jù)編碼不同,ystoe文件分為很多種,did使用的是Java標(biāo)準(zhǔn)yste格式JKS(JavayStoage),所以通過(guò)AndidStudio導(dǎo)出的ystoe文件是.s結(jié)尾的。EnhancedMail)和der(DistinguishedEncodingRules)。jks使用的是der格式,Android也支持直兩種證書編碼格式的區(qū)DER(DistinguishedEncoding二進(jìn)制格式,所有類型的證書和私鑰都可以存儲(chǔ)為der格式PEM(PrivacyEnhancedbase64編碼,內(nèi)容以BEGINxxxbase64編碼,內(nèi)容以BEGINxxx開頭,以END 結(jié)尾jarsigner和apksigner的區(qū)dod提供了兩種對(duì)Ak的簽名方式,一種是基于JAR的簽名方式,另一種是基于Apk的簽名方式,它們的主要區(qū)別在于使用的簽名文件不一樣:rsigner使用ystoe文件進(jìn)行簽名;pksger除了支持使用ystoe文件進(jìn)行簽名外,還支持直接指定pem證書文件和私鑰進(jìn)行簽名。在簽名時(shí),除了要指定keystore文件和密碼外,也要指定alias和key的密碼,這是為什么呢ytoe是一個(gè)密鑰庫(kù),也就是說(shuō)它可以存儲(chǔ)多對(duì)密鑰和證書,ystoe的密碼是用于保護(hù)ystoe本身的,一對(duì)密鑰和證書是通過(guò)is來(lái)區(qū)分的。所以jarsigner是支持使用多個(gè)證書對(duì)Apk進(jìn)行簽名的,pksger也同樣支持。AndroidApkV1簽名原1、解析出CERT.RSA文件中的證書、公鑰,解密CERT.RSA中的加密數(shù)據(jù)2、解密結(jié)果和CERT.SF的指紋進(jìn)行對(duì)比,保證CERT.SF沒(méi)有3、而CERT.SF中的內(nèi)容再和MANIFEST.MF指紋對(duì)比,保證MANIFEST.MF文件沒(méi)有被篡改4、MANIFEST.MF中的內(nèi)容和APK所有文件指紋逐一對(duì)比,保證APK沒(méi)有被篡改JVM和DalvikJVM:.java->javac->.class->jar->架構(gòu):堆和棧的架構(gòu)DVM:.java->javac->.class->dx.bat->架構(gòu):寄存器(cpu上的一塊高速緩存Android2個(gè)虛擬機(jī)的區(qū)別(一個(gè)5.0之前,一個(gè)5.0之后什么是akDk是Goe公司自己設(shè)計(jì)用于Andid平臺(tái)的Java虛擬機(jī)。Dlvik虛擬機(jī)是Gle等廠商合作開發(fā)的Andid移動(dòng)設(shè)備平臺(tái)的核心組成部分之一,它可以支持已轉(zhuǎn)換為.x(即atl)格式的Java應(yīng)用程序的運(yùn)行,.x格式是專為vkak經(jīng)過(guò)優(yōu)化,允許在有限的內(nèi)存中同時(shí)運(yùn)行多個(gè)虛擬機(jī)的實(shí)例,并且每一Dk應(yīng)用作為獨(dú)立的ix進(jìn)程執(zhí)行。獨(dú)立的進(jìn)程可以防止在虛擬機(jī)崩潰的時(shí)候所有程序都被關(guān)閉什么是AT:Andd操作系統(tǒng)已經(jīng)成熟,Goole的dd團(tuán)隊(duì)開始將注意力轉(zhuǎn)向一些底層組件,其中之一是負(fù)責(zé)應(yīng)用程序運(yùn)行的k運(yùn)行時(shí)。Gooe開發(fā)者已經(jīng)花了兩年時(shí)間開發(fā)更快執(zhí)行效率更高更省電的替代ART運(yùn)行時(shí)。ART代表Andidum,其處理應(yīng)用程序執(zhí)行的方式完全不同于ak,k是依靠一個(gè)Jus-nTime(JIT)編譯器去解釋字節(jié)碼。開發(fā)者編譯后的應(yīng)用代碼需要通過(guò)一個(gè)解釋器在用戶的設(shè)備上運(yùn)行,這一機(jī)制并不高效,但讓應(yīng)用能更容易在不同硬件和架構(gòu)上運(yùn)行。ART則完全改變了這套做法,在應(yīng)用安裝的時(shí)候就預(yù)編譯字節(jié)碼為機(jī)器語(yǔ)言,這一機(jī)制叫Ahd-OfTm(T)編譯。在移除解釋代碼這一過(guò)程后,應(yīng)用程序執(zhí)行將更有效率,啟動(dòng)更ART優(yōu)點(diǎn)系統(tǒng)性能的顯著提升支持更低的硬件ART缺點(diǎn)ART缺點(diǎn)Java調(diào)用在Java中聲明Native方法(即需要調(diào)用的本地方法編譯上述Java源文件javac(得到.class文件)3過(guò)javah命令導(dǎo)出JNI的頭文件(.h文件)使用Java需要交互的本地代碼實(shí)現(xiàn)在Java中聲明的Native方法編譯.so庫(kù)文通過(guò)Java命令執(zhí)C++調(diào)用Java程序,最終實(shí)現(xiàn)Java調(diào)用從classpath路徑下搜索ClassMethod這個(gè)類,并返回該類的Class對(duì)象創(chuàng)建該類的實(shí)例調(diào)用對(duì)象的實(shí)例方法JNIEXPORTvoid(JNIEnv*env,jclasscls){jclassclazz=NULL;jobjectjobj=jmethodIDmid_instance=NULL;jstringstr_arg=NULL;//1、從classpath路徑下搜索ClassMethod這個(gè)類,并返回該類的Classif(clazz==NULL){}//2、獲取類的默認(rèn)構(gòu)造方法if(mid_construct==NULL){}//3、查找實(shí)例方法的三、Android優(yōu)秀三三、Android優(yōu)秀三方這個(gè)庫(kù)是做什么用的網(wǎng)絡(luò)底層庫(kù),它是基于ttp協(xié)議封裝的一套請(qǐng)求客戶端,雖然它也可以開線程,但根本上它更偏向真正的請(qǐng)求,跟Httpnt,Htpnectn的職責(zé)是一樣的。其中封裝了網(wǎng)絡(luò)請(qǐng)求get、pt等底層操作的實(shí)現(xiàn)。為什么要在項(xiàng)目中使用這個(gè)OkHttp提供了對(duì)最新的HTTP協(xié)議版本HTTP/2SPDY的支持,這使得對(duì)同一個(gè)主機(jī)發(fā)出的所如果HTTP/2和SPDY不可用,OkHttp會(huì)使用連接池來(lái)復(fù)用連接以提高效OkHttp提供了對(duì)GZIP的默認(rèn)支持來(lái)降低傳輸內(nèi)容的大OkHttp也提供了對(duì)HTTP響應(yīng)的緩存機(jī)制,可以避免不必要的網(wǎng)絡(luò)請(qǐng)求。當(dāng)網(wǎng)絡(luò)出現(xiàn)問(wèn)題時(shí),OkHttp會(huì)自動(dòng)重試一個(gè)主機(jī)的多個(gè)IP地址。這個(gè)庫(kù)都有哪些用法?對(duì)應(yīng)什么樣的使用場(chǎng)get、post請(qǐng)求、上傳文件、上傳表單等這個(gè)庫(kù)的優(yōu)缺點(diǎn)是什么,跟同類型庫(kù)的比優(yōu)點(diǎn):在上if(mid_instance==NULL)}//4if(jobj==NULL){法}//5str_arg=(*env)->NewStringUTF(env,"我是實(shí)例方法//刪除局部}缺點(diǎn):使用的時(shí)候仍然需要缺點(diǎn):使用的時(shí)候仍然需要自己再做一層封這個(gè)庫(kù)的核心實(shí)現(xiàn)原理是什么?如果讓你實(shí)現(xiàn)這個(gè)庫(kù)的某些核心功能,你會(huì)考慮怎么去實(shí)OkHtp內(nèi)部的請(qǐng)求流程:使用Okp會(huì)在請(qǐng)求的時(shí)候初始化一個(gè)l的實(shí)例,然后執(zhí)行它的ecute()方法或eue)方法,內(nèi)部最后都會(huì)執(zhí)行到etRpnseWntecept()方法,這個(gè)方法里面通過(guò)攔截器組成的責(zé)任鏈,依次經(jīng)過(guò)用戶自定義普通攔截器、重試攔截器、橋接攔截器、緩存攔截器、連接攔截器和用戶自定義網(wǎng)絡(luò)攔截器以及訪問(wèn)服務(wù)器攔截器等攔截處理過(guò)程,來(lái)獲取到一個(gè)響應(yīng)并交給用戶。其中,除了OKHtp的內(nèi)部請(qǐng)求流程這點(diǎn)之外,緩存和連接這兩部分內(nèi)容也是兩個(gè)很重要的點(diǎn),掌握了這3點(diǎn)就說(shuō)明你理解了OkHttp。各個(gè)攔截器的作用rgntectr:請(qǐng)求時(shí),對(duì)必要的Header進(jìn)行一些添加,接收響應(yīng)時(shí),移除必要的rIecer:負(fù)責(zé)讀取緩存直接返回(根據(jù)請(qǐng)求的信息和緩存的響應(yīng)的信息來(lái)判斷是否存在緩存可用)、更新緩存1、判斷連接是否可用,不可用則從CnectnPool獲取連接,ontnPoolonectnPool。3、使用連接復(fù)用省去了進(jìn)行TCP和TLS握手的一個(gè)過(guò)程。networkInterceptors:用戶定義網(wǎng)絡(luò)攔截CallServerInterceptor:負(fù)責(zé)向服務(wù)器發(fā)送請(qǐng)求數(shù)據(jù)、從服務(wù)器讀取響你從這個(gè)庫(kù)中學(xué)到什么有價(jià)值的或者說(shuō)可借鑒的設(shè)計(jì)思使用責(zé)任鏈模式實(shí)現(xiàn)攔截器的分層設(shè)計(jì),每一個(gè)攔截器對(duì)應(yīng)一個(gè)功能,充分實(shí)現(xiàn)了功能解耦,易維手寫攔截器網(wǎng)絡(luò)請(qǐng)求緩存處理,okhttp如何處理網(wǎng)絡(luò)緩存的HttpUrlConnectionokhttp關(guān)系?oly:支持TTPS。緩存、異步請(qǐng)求,不支持同步請(qǐng)求。協(xié)議類型是1.0,Htt/.用的是tpUrlnectn/ttpCnt,數(shù)據(jù)讀寫使用的IO。OkHttp:支持HTTPS。緩存、異步請(qǐng)求、同步請(qǐng)求。協(xié)議類型是Http/1.0Http/1.1SPDY,Http/2.0,Okhttp的子系統(tǒng)層級(jí)結(jié)構(gòu)圖如下所示網(wǎng)絡(luò)配置層:利用Bu網(wǎng)絡(luò)配置層:利用Buer模式配置各種參數(shù),例如:超時(shí)時(shí)間、攔截器等,這些參數(shù)都會(huì)由Okttp分發(fā)給各個(gè)需要的子系統(tǒng)。重定向?qū)樱贺?fù)責(zé)重定向Header拼接層:負(fù)責(zé)把用戶構(gòu)造的請(qǐng)求轉(zhuǎn)換為發(fā)送給服務(wù)器的請(qǐng)求,把服務(wù)器返回的響應(yīng)轉(zhuǎn)換為對(duì)用戶友好的響應(yīng)。HTTP緩存層:負(fù)責(zé)讀取緩存以及更新緩連接層:連接層是一個(gè)比較復(fù)雜的層級(jí),它實(shí)現(xiàn)了網(wǎng)絡(luò)協(xié)議、內(nèi)部的攔截器、安全性認(rèn)證,連接與連接池等功能,但這一層還沒(méi)有發(fā)起真正的連接,它只是做了連接器一些參數(shù)的處理。數(shù)據(jù)響應(yīng)層:負(fù)責(zé)從服務(wù)器讀取響應(yīng)的數(shù)在整個(gè)Okhttp的系統(tǒng)中,我們還要理解以下幾個(gè)關(guān)鍵角OkHttpClient:通信的客戶端,用來(lái)統(tǒng)一管理發(fā)起請(qǐng)求與解析響RequestBody:請(qǐng)求體,用來(lái)提交流、表單等請(qǐng)求信息Response:HTTP請(qǐng)求的響應(yīng),獲取響應(yīng)信息,例如:響應(yīng)headerIr是請(qǐng)求攔截器,負(fù)責(zé)攔截并處理請(qǐng)求,它將網(wǎng)絡(luò)請(qǐng)求、緩存、透明壓縮等功能都統(tǒng)一起來(lái),每個(gè)功能都是一個(gè)Itcer,所有的Ictr最終連接成一個(gè)RouteDatabase:記錄連接失敗的Route黑名單自己去設(shè)計(jì)網(wǎng)絡(luò)請(qǐng)求框架,怎么從網(wǎng)絡(luò)加載一個(gè)10M的圖片,說(shuō)下注意事項(xiàng)?http怎么知道文件過(guò)大是否傳輸完畢的響應(yīng)?談?wù)勀銓?duì)ebSocet的理解?WebSocket與socket的區(qū)這個(gè)庫(kù)是做什么用的Retro?t是一個(gè)RESTful的HTTP網(wǎng)絡(luò)請(qǐng)求框架的封裝。Retro?t2.0開始內(nèi)置OkHttp,前者專注于接為什么要在項(xiàng)目中使用這個(gè)1、功能強(qiáng)支持同步、支持多種數(shù)據(jù)的解析&序列化格式2、簡(jiǎn)潔易采用大量設(shè)計(jì)模式簡(jiǎn)化使3、可擴(kuò)展性好功能模塊高度封解耦徹底,如自定義這個(gè)庫(kù)都有哪些用法?對(duì)應(yīng)什么樣的使用場(chǎng)任何網(wǎng)絡(luò)場(chǎng)景都應(yīng)該優(yōu)先選擇,特別是后臺(tái)API遵循RestfulAPI設(shè)計(jì)風(fēng)格&項(xiàng)目中使用到RxJava這個(gè)庫(kù)的優(yōu)缺點(diǎn)是什么,跟同類型庫(kù)的比優(yōu)點(diǎn):在上缺點(diǎn):擴(kuò)展性差,高度封裝所帶來(lái)的必然后果,如果服務(wù)器不能給出統(tǒng)一的API理。這個(gè)庫(kù)的核心實(shí)現(xiàn)原理是什么?如果讓你實(shí)現(xiàn)這個(gè)庫(kù)的某些核心功能,你會(huì)考慮怎么去實(shí)et?t主要是在eate方法中采用動(dòng)態(tài)代理模式(通過(guò)訪問(wèn)代理對(duì)象的方式來(lái)間接訪問(wèn)目標(biāo)對(duì)象)實(shí)現(xiàn)接口方法,這個(gè)過(guò)程構(gòu)建了一個(gè)SrveMhd對(duì)象,根據(jù)方法注解獲取請(qǐng)求方式,參數(shù)類型和參數(shù)注解拼接請(qǐng)求的鏈接,當(dāng)一切都準(zhǔn)備好之后會(huì)把數(shù)據(jù)添加到Rtt的euestBude中。然后當(dāng)我們主動(dòng)發(fā)起網(wǎng)絡(luò)請(qǐng)求的時(shí)候會(huì)調(diào)用khttp發(fā)起網(wǎng)絡(luò)請(qǐng)求,kttp的配置包括請(qǐng)求方式,UL等在Ret的euestBudrl)方法中實(shí)現(xiàn),并發(fā)起真正的網(wǎng)絡(luò)請(qǐng)求。你從這個(gè)庫(kù)中學(xué)到什么有價(jià)值的或者說(shuō)可借鑒的設(shè)你從這個(gè)庫(kù)中學(xué)到什么有價(jià)值的或者說(shuō)可借鑒的設(shè)計(jì)思內(nèi)部使用了優(yōu)秀的架構(gòu)設(shè)計(jì)和大量的設(shè)計(jì)模式,在我分析過(guò)Rtt最新版的源碼和大量?jī)?yōu)秀的t源碼分析文章后,我發(fā)現(xiàn),要想真正理解et?t內(nèi)部的核心源碼流程和設(shè)計(jì)思想,首先,需要對(duì)它使用到的九大設(shè)計(jì)模式有一定的了解,下面我簡(jiǎn)單說(shuō)一說(shuō):1、創(chuàng)建Retro?t實(shí)例使用建造者模式通過(guò)內(nèi)部Buer類建立了一個(gè)Rtoft網(wǎng)絡(luò)請(qǐng)求工廠使用了工廠方法模式。2、創(chuàng)建網(wǎng)絡(luò)請(qǐng)求接口的實(shí)接著,使用了建造者模式&單例模式創(chuàng)建了serviceMethod對(duì)象再者,使用了策略模式對(duì)serviceMethod對(duì)象進(jìn)行網(wǎng)絡(luò)請(qǐng)求參數(shù)配置,即通過(guò)解析網(wǎng)絡(luò)請(qǐng)求接口方法的參數(shù)、返回值和注解類型,從Rt?t對(duì)象中獲取對(duì)應(yīng)的網(wǎng)絡(luò)的url地址、網(wǎng)絡(luò)請(qǐng)求執(zhí)行器、網(wǎng)絡(luò)請(qǐng)求適配器和數(shù)據(jù)轉(zhuǎn)換器。最后,使用了裝飾者模式EctelBackserviceMethodHandr從子線程切換到主線程從而對(duì)返回?cái)?shù)據(jù)結(jié)果進(jìn)行處理。3、發(fā)送網(wǎng)絡(luò)請(qǐng)求在異步請(qǐng)求時(shí),通過(guò)靜態(tài)delegate代理對(duì)網(wǎng)絡(luò)請(qǐng)求接口的方法中的每個(gè)參數(shù)使用對(duì)ParameterHanlder進(jìn)行解析4、解析數(shù)5、切換線使用了適配器模式通過(guò)檢測(cè)不同的Plfrm使用不同的回調(diào)執(zhí)行器,然后使用回調(diào)執(zhí)行器切換線程,這里同樣是使用了裝飾模式。6、處理結(jié)Android:主流網(wǎng)絡(luò)請(qǐng)求開源庫(kù)的對(duì)比(Android-Async-Http、Volley、OkHttp、三、響應(yīng)式編程框架:RxJava實(shí)現(xiàn)原RxJava變換操作符map?atMapconcatMapmap:【數(shù)據(jù)類型轉(zhuǎn)換】將被觀察者發(fā)送的事件轉(zhuǎn)換為另一種類型的事件?atMap:【化解循環(huán)嵌套和接口嵌套】將被觀察者發(fā)送的事件序列進(jìn)行拆分&轉(zhuǎn)換后合并成一concatMap:【有序】與?atMap的區(qū)別在于,拆分&重新合并生成的事件序列的順序者舊序列生產(chǎn)的順序一致定期從被觀察者發(fā)送的事件中獲取一定數(shù)量的事件并放到緩存區(qū)中,然后把這些數(shù)據(jù)集合打包發(fā)射。RxJava中map和?atmap操作符的區(qū)別及底層實(shí)手寫rxjava遍歷數(shù)組你認(rèn)為Rxjava的線程池與你們自己實(shí)現(xiàn)任務(wù)管理框架有什么區(qū)這個(gè)庫(kù)是做什么用的Glide是Android中的一個(gè)圖片加Glide是Android中的一個(gè)圖片加載庫(kù),用于實(shí)現(xiàn)圖片加為什么要在項(xiàng)目中使用這個(gè)1、多樣化媒體加載:不僅可以進(jìn)行圖片緩存,還支持Gif、WebP、縮略圖,甚至是Video2、通過(guò)設(shè)置綁定生命周期:可以使加載圖片的生命周期動(dòng)態(tài)管理起3、高效的緩存策略:支持內(nèi)存、isk緩存,并且Passo只會(huì)緩存原始尺寸的圖片,內(nèi)Glie多種規(guī)格,也就是Glde會(huì)根據(jù)你Imageiw的大小來(lái)緩存相應(yīng)大小的圖片尺寸。4、內(nèi)存開銷?。耗J(rèn)的Bitmap格式是RGB_565格式,而Passo默認(rèn)的是AGB_888小一半。這個(gè)庫(kù)都有哪些用法?對(duì)應(yīng)什么樣的使用場(chǎng)4、可以配置磁盤緩存策略ALL、NONE、SOURCE、RESULT這個(gè)庫(kù)的優(yōu)缺點(diǎn)是什么,跟同類型庫(kù)的比庫(kù)比較大,源碼實(shí)現(xiàn)復(fù)這個(gè)庫(kù)的核心實(shí)現(xiàn)原理是什么?如果讓你實(shí)現(xiàn)這個(gè)庫(kù)的某些核心功能,你會(huì)考慮怎么去實(shí)設(shè)置請(qǐng)求url,并記錄url已設(shè)置的狀態(tài)3、2、遞歸建立縮略圖請(qǐng)求,沒(méi)有縮略圖請(qǐng)求,則直接進(jìn)行正常請(qǐng)4、engine是一個(gè)負(fù)責(zé)加載和管理緩存資源常規(guī)三級(jí)緩存的流程:強(qiáng)引用->軟引用->硬盤緩當(dāng)我們的APP中想要加載某張圖片時(shí),先去ruace中尋找圖片,如果LruCche中有,則直接取出來(lái)使用,如果LrCache中沒(méi)有,則去Softefeece中尋找(軟引用適合當(dāng)cache,當(dāng)內(nèi)存吃緊的時(shí)候才會(huì)被回收。而ekfeence在每次systc()就會(huì)被回收)(當(dāng)ruaceSftefeee中),如果Sftefeee中有,則從Sftefeee中取出圖片使用,同時(shí)將圖片重新放回到rCache中,如果Sftefeee中也沒(méi)有圖片,則去硬盤緩存中中尋找,如果有則取出來(lái)使用,同時(shí)將圖片添加到rCache中,如果沒(méi)有,則連接網(wǎng)絡(luò)從網(wǎng)上下載圖片。圖片下載完成后,將圖片保存到硬盤緩存中,然后放到LrCace中。Glide的三層緩存機(jī)制Glide緩存機(jī)制Glide緩存機(jī)制大致分為三層:內(nèi)存緩存、弱引用緩存、磁盤緩存的順序是:弱引用、內(nèi)存、磁三層存儲(chǔ)的機(jī)制在Enie中實(shí)現(xiàn)的。先說(shuō)下Enie是什么?Enie這一層負(fù)責(zé)加載時(shí)做管理內(nèi)存緩存的邏輯。持有MryCache、M<K,efeEiRuc<?>>>。通過(guò)ad()來(lái)加載圖片,加載前后會(huì)做內(nèi)存存儲(chǔ)的邏輯。如果內(nèi)存緩存中沒(méi)有,那么才會(huì)使用Enob這一層來(lái)進(jìn)行異步獲取硬盤資源或網(wǎng)絡(luò)資源。EeJob類似一個(gè)異步線程或bservable。Enie是一個(gè)全局唯一的,通過(guò)Gld.etEnie()來(lái)獲取。需要一個(gè)圖片資源,如果rache中有相應(yīng)的資源圖片,那么就返回,同時(shí)從Lruche中清除,放到iveesouces中。ivesucesmp是盛放正在使用的資源,以弱引用的形式存在。同時(shí)資源內(nèi)部有被引用的記錄。如果資源沒(méi)有引用記錄了,那么再放回Lrucce中,同時(shí)從iveesouces中清除。如果rache中沒(méi)有,就從activesuces中找,找到后相應(yīng)資源引用加1。如果rache和iveesouces中沒(méi)有,那么進(jìn)行資源異步請(qǐng)求(網(wǎng)絡(luò)/iskLrace),請(qǐng)求成功后,資源放到che和iveRouces中。Glide源碼機(jī)制的核心思使用一個(gè)弱引用mapivesuces來(lái)盛放項(xiàng)目中正在使用的資源。ucacheucache需要移除一個(gè)緩存時(shí),會(huì)調(diào)用esouce.()方法。注意到該方法上面注釋寫著只有沒(méi)有任何consumer引用該資源的時(shí)候才可以調(diào)用這個(gè)方法。那么為什么調(diào)用esouce.()方法需要保證該資源沒(méi)有任何consumer引用呢?glideesouce定義的cyc()要做的事情是把這個(gè)不用的資源(假設(shè)是bmap或dwbe)放到btmapol中。btmapol是一個(gè)bmp回收再利用的庫(kù),在做tnsform的時(shí)候會(huì)從這個(gè)btmpol中拿一個(gè)bmp進(jìn)行再利用。這樣就避免了重新創(chuàng)建map,減少了內(nèi)存的開支。而既然btmpol中的bmp會(huì)被重復(fù)利用,那么肯定要保證回收該資源的時(shí)候(即調(diào)用資源的cycle()時(shí)),要保證該資源真的沒(méi)有外界引用了。這也是為什么glide花費(fèi)那么多邏輯來(lái)保證Lrucce中的資源沒(méi)有外界引用的原因。你從這個(gè)庫(kù)中學(xué)到什么有價(jià)值的或者說(shuō)可借鑒的設(shè)計(jì)思Glide的高效的三層緩存機(jī)制,如圖片占用內(nèi)存的計(jì)算公式:圖片高度*圖片寬度*一個(gè)像素占用的內(nèi)存大小。所以,計(jì)算圖片占用內(nèi)存大小的時(shí)候,要考慮圖片所在的目錄跟設(shè)備密度,這兩個(gè)因素其實(shí)影響的是圖片的寬高,anod會(huì)對(duì)圖片進(jìn)行拉升跟壓縮。加載bitmap過(guò)程(怎樣保證不產(chǎn)生內(nèi)存溢出由于Android對(duì)圖片使用內(nèi)存有限制,若是加載幾兆的大圖片便內(nèi)存溢出。Bitmap會(huì)將圖片的所有像(即長(zhǎng)x寬)加載到內(nèi)存中,如果圖片分辨率過(guò)大,會(huì)直接導(dǎo)致內(nèi)存OOM,只有在BapFactry圖片時(shí)使用BtmpFactorOptns對(duì)相關(guān)參數(shù)進(jìn)行配置來(lái)減少加載的像素。BitmapFactory.Options相關(guān)參數(shù)詳解(1).Options.inPreferredCon?g值來(lái)降低內(nèi)存消耗比如:(1).Options.inPreferredCon?g值來(lái)降低內(nèi)存消耗比如:默認(rèn)值A(chǔ)RGB_8888改為RGB_565,節(jié)約一半內(nèi)(2).設(shè)置Options.inSampleSize縮放比例,對(duì)大圖片進(jìn)行壓縮(3).設(shè)置Options.inPurgeable和inInputShareable:讓系統(tǒng)能及時(shí)回收內(nèi)(4).使用decodeStream代替decodeResource等其他方在Android應(yīng)用的開發(fā)中,為了防止內(nèi)存溢出,在處理一些占用內(nèi)存大而且生命周期較長(zhǎng)的對(duì)象時(shí)候,1、軟/弱引用可以和一個(gè)引用隊(duì)列(Reeu)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收器回收,Java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。利用這個(gè)隊(duì)列可以得知被回收的軟/弱引用的對(duì)象列表,從而為緩沖器清除已失效的軟/弱引用。2、如果只2、如果只是想避免OOM異常的發(fā)生,則可以使用軟引用。如果對(duì)于應(yīng)用的性能更在意,想盡快3、可以根據(jù)對(duì)象是否經(jīng)常使用來(lái)判斷選擇軟引用還是弱引用。如果該對(duì)象可能會(huì)經(jīng)常使用的,就盡量用軟引用。如果該對(duì)象不被使用的可能性更大些,就可以用弱引用。Android里的內(nèi)存緩存和磁盤緩存是怎么實(shí)現(xiàn)的內(nèi)存緩存基于LruCache實(shí)現(xiàn),磁盤緩存基于DiskLruCache實(shí)現(xiàn)。這兩個(gè)類都基于Lru算法LinkedHashMap來(lái)實(shí)現(xiàn)LRU算法可以用一句話來(lái)描述,如下所RU是LetecntlyUsed的縮寫,最近最少使用算法,從它的名字就可以看出,它的核心原則是如果一個(gè)數(shù)據(jù)在最近一段時(shí)間沒(méi)有使用到,那么它在將來(lái)被訪問(wèn)到的可能性也很小,則這類數(shù)據(jù)項(xiàng)會(huì)被優(yōu)先淘汰掉。LruCache原之前,我們會(huì)使用內(nèi)存緩存技術(shù)實(shí)現(xiàn),也就是軟引用或弱引用,在Android2.3(APILevel9)開始,垃其實(shí)LU緩存的實(shí)現(xiàn)類似于一個(gè)特殊的棧,把訪問(wèn)過(guò)的元素放置到棧頂(若棧中存在,則更新至棧頂;若棧中不存在則直接入棧),然后如果棧中元素?cái)?shù)量超過(guò)限定值,則刪除棧底元素(元素)。它的內(nèi)部存在一個(gè)LinkedHashMap和maxSize,把最近使用的對(duì)象用強(qiáng)引用存儲(chǔ)在LinkedHashMap中,給出來(lái)put和get方法,每次put圖片時(shí)計(jì)算緩存中所有圖片的總大小,跟maxSize進(jìn)行比較,大于maxSize,就將最久添加的圖片移除,反之小于maxSize就添加進(jìn)來(lái)。rCache的原理就是利用dashMp持有對(duì)象的強(qiáng)引用,按照Lru算法進(jìn)行對(duì)象淘汰。具體說(shuō)來(lái)假設(shè)我們從表尾訪問(wèn)數(shù)據(jù),在表頭刪除數(shù)據(jù),當(dāng)訪問(wèn)的數(shù)據(jù)項(xiàng)在鏈表中存在時(shí),則將該數(shù)據(jù)項(xiàng)移動(dòng)到表尾,否則在表尾新建一個(gè)數(shù)據(jù)項(xiàng)。當(dāng)鏈表容量超過(guò)一定閾值,則移除表頭的數(shù)據(jù)。詳細(xì)來(lái)說(shuō)就是rCache中維護(hù)了一個(gè)集合dHsMp,該ndashMap是以訪問(wèn)順序排序的。當(dāng)調(diào)用ut()方法時(shí),就會(huì)在結(jié)合中添加元素,并調(diào)用trimoize()用ndHsMp的迭代器刪除隊(duì)頭元素,即近期最少訪問(wèn)的元素。當(dāng)調(diào)用et()方法訪問(wèn)緩存對(duì)象時(shí),就會(huì)調(diào)用dashMpet()方法獲得對(duì)應(yīng)集合元素,同時(shí)會(huì)更新該元素到隊(duì)尾。LruCacheput方法核心在添加過(guò)緩存對(duì)象后,調(diào)用trimoSize()方法,來(lái)判斷緩存是否已滿,如果滿了就要?jiǎng)h除近期最少使用的對(duì)象。trimoSize()方法不斷地刪除indashMap中隊(duì)頭的元素,即近期最少訪問(wèn)的,直到緩存大小小于最大值(mxSize)。LruCacheget方法核心邏當(dāng)調(diào)用LrCace的et()方法獲取集合中的緩存對(duì)象時(shí),就代表訪問(wèn)了一次該元素,將會(huì)更新隊(duì)列,保持整個(gè)隊(duì)列是按照訪問(wèn)順序排序的。為什么會(huì)選擇LinkedHashMap呢這跟LinkedHashMap的特性有關(guān),LinkedHashMap的構(gòu)造函數(shù)里有個(gè)布爾參數(shù)accessOrder,當(dāng)它true時(shí),LinkedHashMap會(huì)以訪問(wèn)順序?yàn)樾蚺帕性?,否則以插入順序?yàn)樾蚺判蛟狶inkedHashMap原LinkedHashMap幾乎和HashMap一樣:從技術(shù)上來(lái)說(shuō),不同的是它定義了一個(gè)Entry<K,V>header,這個(gè)header不是放在Table里,它是額外獨(dú)立出來(lái)的。LinkedHashMap通過(guò)繼承hashMap中的Entry<K,V>,并添加兩個(gè)屬性Entry<K,V>before,after,和header結(jié)合起來(lái)組成一個(gè)雙向DisLruCache原DiskLruCache與LruCache原理相似,只是DisLruCache原DiskLruCache與LruCache原理相似,只是多了一個(gè)journal文件來(lái)做磁盤文件的管理,如下所11DIRTYCLEAN1517126350519REMOVE注:這里的緩存目錄是應(yīng)用的緩存目錄et的手機(jī)可以通過(guò)以下命令進(jìn)入到該目錄中或者將該目錄整體拷貝出來(lái):我們來(lái)分析下這個(gè)文件的內(nèi)第一行:lio.Diskuhe第二行:1,DkCe源碼版本號(hào)。第五行:空第六行及后續(xù)行:緩存操作記第六行及后續(xù)行表示緩存操作記錄,關(guān)于操作記錄,我們需要了解以下三DIRTY表示一個(gè)entry正在被寫入。寫入分兩種情況,如果成功會(huì)緊接著寫入一行CLEAN的記錄;如果當(dāng)手動(dòng)調(diào)用remove(key)方法的時(shí)候也會(huì)寫入一條REMOVE記錄READ就是說(shuō)明有一次讀取的記CLEAN的后面還記錄了文件的長(zhǎng)度,注意可能會(huì)一個(gè)key對(duì)應(yīng)多個(gè)文件,那么就會(huì)有多個(gè)數(shù)Bitmap壓縮策加載Bitmap的方式BitmapFactory四類方decodeFile(文件系統(tǒng))decodeResourece(資源)decodeStream(輸入流)BitmapFactory.options參數(shù)nSamlSze采樣率,對(duì)圖片高和寬進(jìn)行縮放,以最小比進(jìn)行縮放(一般取值為2的指數(shù))常是根據(jù)圖片寬高實(shí)際的大小/需要的寬高大小,分別計(jì)算出寬和高的縮放比。但應(yīng)該取其中最小的縮放比,避免縮放圖片太小,到達(dá)指定控件中不能鋪滿,需要拉伸從而導(dǎo)致模糊。adbshellrun-ascpadbbackupnoapkcom.your.packagenameinJustDecodeBounds獲取圖片的寬高信息,交給inSampleSize參數(shù)inJustDecodeBounds獲取圖片的寬高信息,交給inSampleSize參數(shù)選擇縮放比。通過(guò)inJustDecodeBounds=true,然后加載圖片就可以實(shí)現(xiàn)只解析圖片的寬高信息,并不會(huì)真正的加inJustDecodeBoundsfalse,再重新加載圖片,就可以加載縮放后的圖片。高效加載Bitmap的流程1、將BitmapFactory.Options的inJustDecodeBounds參數(shù)設(shè)為true并加載圖2、從B

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論