1水醋、Activity生命周期?
onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDetroy()
2、Service生命周期友浸?
service 啟動方式有兩種
一種是通過startService()方式進(jìn)行啟動
另一種是通過bindService()方式進(jìn)行啟動拆又。
不同的啟動方式他們的生命周期是不一樣.
通過startService()這種方式啟動的service
生命周期是這樣:
調(diào)用startService() --> onCreate()--> onStartConmon()--> onDestroy()。
這種方式啟動的話温兼,需要注意一下幾個問題
第一:當(dāng)我們通過startService被調(diào)用以后秸滴,多次在調(diào)用startService(),onCreate()方法也只會被調(diào)用一次,而onStartConmon()會被多次調(diào)用募判,當(dāng)我們調(diào)用stopService()的時(shí)候荡含,onDestroy()就會被調(diào)用,從而銷毀服務(wù)届垫。
第二:當(dāng)我們通過startService啟動時(shí)候释液,通過intent傳值,在onStartConmon()方法中獲取值的時(shí)候装处,一定要先判斷intent是否為null误债。
通過bindService()方式進(jìn)行綁定,這種方式綁定service
生命周期:
bindService-->onCreate()-->onBind()-->unBind()-->onDestroy()
bindservice 這種方式進(jìn)行啟動service好處是更加便利activity中操作service,如果要在activity中調(diào)用妄迁,在需要在activity獲取ServiceConnection對象寝蹈,通過ServiceConnection來獲取service中內(nèi)部類的類對象,然后通過這個類對象就可以調(diào)用類中的方法登淘,當(dāng)然這個類需要繼承Binder對象
3箫老、Activity的啟動過程(不要回答生命周期)
app啟動的過程有兩種情況
第一種是從桌面launcher上點(diǎn)擊相應(yīng)的應(yīng)用圖標(biāo)
第二種是在activity中通過調(diào)用startActivity來啟動一個新的activity。
我們創(chuàng)建一個新的項(xiàng)目黔州,默認(rèn)的根activity都是MainActivity耍鬓,而所有的activity都是保存在堆棧中的阔籽,我們啟動一個新的activity就會放在上一個activity上面,而我們從桌面點(diǎn)擊應(yīng)用圖標(biāo)的時(shí)候牲蜀,由于launcher本身也是一個應(yīng)用笆制,當(dāng)我們點(diǎn)擊圖標(biāo)的時(shí)候,系統(tǒng)就會調(diào)用startActivitySately(),一般情況下各薇,我們所啟動的activity的相關(guān)信息都會保存在intent中项贺,比如action,category等等峭判。我們在安裝這個應(yīng)用的時(shí)候开缎,系統(tǒng)也會啟動一個PackaManagerService的管理服務(wù),這個管理服務(wù)會對AndroidManifest.xml文件進(jìn)行解析林螃,從而得到應(yīng)用程序中的相關(guān)信息奕删,比如service,activity疗认,Broadcast等等完残,然后獲得相關(guān)組件的信息。當(dāng)我們點(diǎn)擊應(yīng)用圖標(biāo)的時(shí)候横漏,就會調(diào)用startActivitySately()方法谨设,而這個方法內(nèi)部則是調(diào)用startActivty(),而startActivity()方法最終還是會調(diào)用startActivityForResult()這個方法。而在startActivityForResult()這個方法缎浇。因?yàn)閟tartActivityForResult()方法是有返回結(jié)果的扎拣,所以系統(tǒng)就直接給一個-1,就表示不需要結(jié)果返回了素跺。而startActivityForResult()這個方法實(shí)際是通過Instrumentation類中的execStartActivity()方法來啟動activity二蓝,Instrumentation這個類主要作用就是監(jiān)控程序和系統(tǒng)之間的交互。而在這個execStartActivity()方法中會獲取ActivityManagerService的代理對象指厌,通過這個代理對象進(jìn)行啟動activity刊愚。啟動會就會調(diào)用一個checkStartActivityResult()方法,如果說沒有在配置清單中配置有這個組件踩验,就會在這個方法中拋出異常了鸥诽。當(dāng)然最后是調(diào)用的是Application.scheduleLaunchActivity()進(jìn)行啟動activity,而這個方法中通過獲取得到一個ActivityClientRecord對象晰甚,而這個ActivityClientRecord通過handler來進(jìn)行消息的發(fā)送衙传,系統(tǒng)內(nèi)部會將每一個activity組件使用ActivityClientRecord對象來進(jìn)行描述,而ActivityClientRecord對象中保存有一個LoaderApk對象厕九,通過這個對象調(diào)用handleLaunchActivity來啟動activity組件蓖捶,而頁面的生命周期方法也就是在這個方法中進(jìn)行調(diào)用。
4扁远、Broadcast注冊方式與區(qū)別
此處延伸:什么情況下用動態(tài)注冊......................................................5
Broadcast廣播俊鱼,注冊方式主要有兩種.
第一種是靜態(tài)注冊刻像,也可成為常駐型廣播,這種廣播需要在Androidmanifest.xml中進(jìn)行注冊并闲,這中方式注冊的廣播细睡,不受頁面生命周期的影響,即使退出了頁面帝火,也可以收到廣播這種廣播一般用于想開機(jī)自啟動啊等等溜徙,由于這種注冊的方式的廣播是常駐型廣播,所以會占用CPU的資源犀填。
第二種是動態(tài)注冊蠢壹,而動態(tài)注冊的話,是在代碼中注冊的九巡,這種注冊方式也叫非常駐型廣播图贸,受到生命周期的影響,退出頁面后冕广,就不會收到廣播疏日,我們通常運(yùn)用在更新UI方面。這種注冊方式優(yōu)先級較高撒汉。最后需要解綁沟优,否會會內(nèi)存泄露
廣播是分為有序廣播和無序廣播。
5睬辐、HttpClient與HttpUrlConnection的區(qū)別
此處延伸:Volley里用的哪種請求方式
首先HttpClient和HttpUrlConnection這兩種方式都支持Https協(xié)議净神,都是以流的形式進(jìn)行上傳或者下載數(shù)據(jù),也可以說是以流的形式進(jìn)行數(shù)據(jù)的傳輸溉委,還有ipv6,以及連接池等功能。HttpClient這個擁有非常多的API爱榕,所以如果想要進(jìn)行擴(kuò)展的話瓣喊,并且不破壞它的兼容性的話,很難進(jìn)行擴(kuò)展黔酥,也就是這個原因藻三,Google在Android6.0的時(shí)候,直接就棄用了這個HttpClient.
而HttpUrlConnection相對來說就是比較輕量級了跪者,API比較少棵帽,容易擴(kuò)展,并且能夠滿足Android大部分的數(shù)據(jù)傳輸渣玲。比較經(jīng)典的一個框架volley逗概,在Android 2.3版本以前都是使用Android HttpClient,在Android 2.3以后就使用了HttpUrlConnection。
6忘衍、java虛擬機(jī)和Dalvik虛擬機(jī)的區(qū)別
Java虛擬機(jī):
1逾苫、java虛擬機(jī)基于棧卿城。
基于棧的機(jī)器必須使用指令來載入和操作棧上數(shù)據(jù),所需指令更多更多铅搓。
2瑟押、java虛擬機(jī)運(yùn)行的是java字節(jié)碼。
java類會被編譯成一個或多個字節(jié)碼.class文件.
Dalvik虛擬機(jī):
1星掰、dalvik虛擬機(jī)是基于寄存器的
2多望、Dalvik運(yùn)行的是自定義的.dex字節(jié)碼格式。
java類被編譯成.class文件后氢烘,會通過一個dx工具將所有的.class文件轉(zhuǎn)換成一個.dex文件怀偷,然后dalvik虛擬機(jī)會從其中讀取指令和數(shù)據(jù).
3、常量池已被修改為只使用32位的索引威始,以 簡化解釋器枢纠。
4、一個應(yīng)用黎棠,一個虛擬機(jī)實(shí)例晋渺,一個進(jìn)程
所有android應(yīng)用的線程都是對應(yīng)一個linux線程,都運(yùn)行在自己的沙盒中脓斩,不同的應(yīng)用在不同的進(jìn)程中運(yùn)行木西。每個android dalvik應(yīng)用程序都被賦予了一個獨(dú)立的linux PID(app_*)
7、進(jìn)程彼婢玻活(不死進(jìn)程)
此處延伸:進(jìn)程的優(yōu)先級是什么
當(dāng)前業(yè)界的Android進(jìn)程卑饲В活手段主要分為黑、白燎猛、灰三種恋捆,其大致的實(shí)現(xiàn)思路如下:
黑色保活:
不同的app進(jìn)程重绷,用廣播相互喚醒,包括利用系統(tǒng)提供的廣播進(jìn)行喚醒.
白色狈型#活:啟動前臺Service
灰色保活:利用系統(tǒng)的漏洞啟動前臺Service
黑色闭炎浚活
所謂黑色狈呒兀活,就是利用不同的app進(jìn)程使用廣播來進(jìn)行相互喚醒候醒。舉個3個比較常見的場景:
場景1:開機(jī)能颁,網(wǎng)絡(luò)切換、拍照倒淫、拍視頻時(shí)候伙菊,利用系統(tǒng)產(chǎn)生的廣播喚醒a(bǔ)pp
場景2:接入第三方SDK也會喚醒相應(yīng)的app進(jìn)程,如微信sdk會喚醒微信,支付寶sdk會喚醒支付寶占业。由此發(fā)散開去绒怨,就會直接觸發(fā)了下面的 場景3
場景3:假如你手機(jī)里裝了支付寶、淘寶谦疾、天貓南蹂、UC等阿里系的app,那么你打開任意一個阿里系的app后念恍,有可能就順便把其他阿里系的app給喚醒了六剥。(只是拿阿里打個比方,其實(shí)BAT系都差不多)
白色狈寤铮活
白色绷婆保活手段非常簡單,就是調(diào)用系統(tǒng)api啟動一個前臺的Service進(jìn)程瞳氓,這樣會在系統(tǒng)的通知欄生成一個Notification策彤,用來讓用戶知道有這樣一個app在運(yùn)行著,哪怕當(dāng)前的app退到了后臺匣摘。
灰色钡晔活
灰色保活音榜,這種迸尤常活手段是應(yīng)用范圍最廣泛。它是利用系統(tǒng)的漏洞來啟動一個前臺的Service進(jìn)程赠叼,與普通的啟動方式區(qū)別在于擦囊,它不會在系統(tǒng)通知欄處出現(xiàn)一個Notification,看起來就如同運(yùn)行著一個后臺Service進(jìn)程一樣嘴办。這樣做帶來的好處就是瞬场,用戶無法察覺到你運(yùn)行著一個前臺進(jìn)程(因?yàn)榭床坏絅otification),但你的進(jìn)程優(yōu)先級又是高于普通后臺進(jìn)程的。那么如何利用系統(tǒng)的漏洞呢涧郊,大致的實(shí)現(xiàn)思路和代碼如下:
思路一:API < 18泌类,啟動前臺Service時(shí)直接傳入new Notification();
思路二:API >= 18底燎,同時(shí)啟動兩個id相同的前臺Service,然后再將后啟動的Service做stop處理
熟悉Android系統(tǒng)的童鞋都知道弹砚,系統(tǒng)出于體驗(yàn)和性能上的考慮双仍,app在退到后臺時(shí)系統(tǒng)并不會真正的kill掉這個進(jìn)程,而是將其緩存起來桌吃。打開的應(yīng)用越多朱沃,后臺緩存的進(jìn)程也越多。在系統(tǒng)內(nèi)存不足的情況下,系統(tǒng)開始依據(jù)自身的一套進(jìn)程回收機(jī)制來判斷要kill掉哪些進(jìn)程逗物,以騰出內(nèi)存來供給需要的app搬卒。這套殺進(jìn)程回收內(nèi)存的機(jī)制就叫 Low Memory Killer ,它是基于Linux內(nèi)核的OOM Killer(Out-Of-Memory killer)機(jī)制誕生翎卓。
進(jìn)程的重要性契邀,劃分5級:
前臺進(jìn)程(Foreground process)
可見進(jìn)程 (Visible process)
服務(wù)進(jìn)程(Service process)
后臺進(jìn)程(Background process)
空進(jìn)程 (Empty process)
了解完Low Memory Killer,再科普一下oom_adj失暴。什么是oom_adj坯门?它是 linux內(nèi)核分配給每個系統(tǒng)進(jìn)程的一個值,代表進(jìn)程的優(yōu)先級逗扒,進(jìn)程回收機(jī)制就是根據(jù)這個優(yōu)先級來決定是否進(jìn)行回收古戴。對于oom_adj的作用耀里,你只需要記住以下幾點(diǎn)即可:
進(jìn)程的oom_adj越大侍芝,表示此進(jìn)程優(yōu)先級越低弱匪,越容易被殺回收谊惭;越小孵奶,表示進(jìn)程優(yōu)先級越高燕刻,越不容易被殺回收
普通app進(jìn)程的oom_adj>=0,系統(tǒng)進(jìn)程的oom_adj才可能<0
有些手機(jī)廠商把這些知名的app放入了自己的白名單中塑煎,保證了進(jìn)程不死來提高用戶體驗(yàn)(如微信叨橱、QQ建炫、陌陌都在小米的白名單中)畦韭。如果從白名單中移除,他們終究還是和普通app一樣躲避不了被殺的命運(yùn)肛跌,為了盡量避免被殺艺配,還是老老實(shí)實(shí)去做好優(yōu)化工作吧。
所以衍慎,進(jìn)程弊Γ活的根本方案終究還是回到了性能優(yōu)化上,進(jìn)程永生不死終究是個徹頭徹尾的偽命題稳捆!
8赠法、講解一下Context
Context是一個抽象基類。在翻譯為上下文乔夯,也可以理解為環(huán)境砖织,是提供一些程序的運(yùn)行環(huán)境基礎(chǔ)信息。Context下有兩個子類末荐,ContextWrapper是上下文功能的封裝類侧纯,而ContextImpl則是上下文功能的實(shí)現(xiàn)類。而ContextWrapper又有三個直接的子類甲脏, ContextThemeWrapper眶熬、Service和Application妹笆。其中,ContextThemeWrapper是一個帶主題的封裝類娜氏,而它有一個直接子類就是Activity拳缠,所以Activity和Service以及Application的Context是不一樣的,只有Activity需要主題贸弥,Service不需要主題窟坐。
Context一共有三種類型,分別是Application茂腥、Activity和Service狸涌。這三個類雖然分別各種承擔(dān)著不同的作用,但它們都屬于Context的一種最岗,而它們具體Context的功能則是由ContextImpl類去實(shí)現(xiàn)的帕胆,因此在絕大多數(shù)場景下,Activity般渡、Service和Application這三種類型的Context都是可以通用的懒豹。
不過有幾種場景比較特殊,比如啟動Activity驯用,還有彈出Dialog脸秽。出于安全原因的考慮,Android是不允許Activity或Dialog憑空出現(xiàn)的蝴乔,一個Activity的啟動必須要建立在另一個Activity的基礎(chǔ)之上记餐,也就是以此形成的返回棧。而Dialog則必須在一個Activity上面彈出(除非是System Alert類型的Dialog)薇正,因此在這種場景下片酝,我們只能使用Activity類型的Context,否則將會出錯挖腰。
getApplicationContext()和getApplication()方法得到的對象都是同一個application對象雕沿,只是對象的類型不一樣。
Context數(shù)量 = Activity數(shù)量 + Service數(shù)量 + 1 (1為Application)
9猴仑、理解Activity审轮,View,Window三者關(guān)系
這個問題真的很不好回答。所以這里先來個算是比較恰當(dāng)?shù)谋扔鱽硇稳菹滤鼈兊年P(guān)系吧辽俗。Activity像一個工匠(控制單元)疾渣,Window像窗戶(承載模型),View像窗花(顯示視圖)LayoutInflater像剪刀崖飘,Xml配置像窗花圖紙稳衬。
1:Activity構(gòu)造的時(shí)候會初始化一個Window,準(zhǔn)確的說是PhoneWindow坐漏。
2:這個PhoneWindow有一個ViewRoot,這個ViewRoot是一個View或者說ViewGroup,是最初始的根視圖赊琳。
3:ViewRoot通過addView方法來一個個的添加View街夭。比如TextView,Button等
4:這些View的事件監(jiān)聽躏筏,是由WindowManagerService來接受消息板丽,并且回調(diào)Activity函數(shù)。比如onClickListener趁尼,onKeyDown等埃碱。
10、四種LaunchMode及其使用場景2019/10/28 17:00:00
此處延伸:棧(First In Last Out)與隊(duì)列(First In First Out)的區(qū)別
棧與隊(duì)列的區(qū)別:
隊(duì)列先進(jìn)先出酥泞,棧先進(jìn)后出
對插入和刪除操作的"限定"砚殿。 棧是限定只能在表的一端進(jìn)行插入和刪除操作的線性表。 隊(duì)列是限定只能在表的一端進(jìn)行插入和在另一端進(jìn)行刪除操作的線性表芝囤。
遍歷數(shù)據(jù)速度不同
standard 模式
這是默認(rèn)模式似炎,每次激活A(yù)ctivity時(shí)都會創(chuàng)建Activity實(shí)例,并放入任務(wù)棧中悯姊。使用場景:大多數(shù)Activity羡藐。
singleTop 模式
如果在任務(wù)的棧頂正好存在該Activity的實(shí)例,就重用該實(shí)例( 會調(diào)用實(shí)例的onNewIntent())悯许,否則就會創(chuàng)建新的實(shí)例并放入棧頂仆嗦,即使棧中已經(jīng)存在該Activity的實(shí)例,只要不在棧頂先壕,都會創(chuàng)建新的實(shí)例瘩扼。使用場景如新聞類或者閱讀類App的內(nèi)容頁面。
singleTask 模式
如果在棧中已經(jīng)有該Activity的實(shí)例启上,就重用該實(shí)例(會調(diào)用實(shí)例的onNewIntent())邢隧。重用時(shí),會讓該實(shí)例回到棧頂冈在,因此在它上面的實(shí)例將會被移出棧倒慧。如果棧中不存在該實(shí)例,將會創(chuàng)建新的實(shí)例放入棧中包券。使用場景如瀏覽器的主界面纫谅。不管從多少個應(yīng)用啟動瀏覽器,只會啟動主界面一次溅固,其余情況都會走onNewIntent付秕,并且會清空主界面上面的其他頁面。
singleInstance 模式
在一個新棧中創(chuàng)建該Activity的實(shí)例侍郭,并讓多個應(yīng)用共享該棧中的該Activity實(shí)例询吴。一旦該模式的Activity實(shí)例已經(jīng)存在于某個棧中掠河,任何應(yīng)用再激活該Activity時(shí)都會重用該棧中的實(shí)例( 會調(diào)用實(shí)例的 onNewIntent())。其效果相當(dāng)于多個應(yīng)用共享一個應(yīng)用猛计,不管誰激活該Activity 都會進(jìn)入同一個應(yīng)用中唠摹。使用場景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設(shè)置分離奉瘤。singleInstance不要用于中間頁面勾拉,如果用于中間頁面,跳轉(zhuǎn)會有問題盗温,比如:A -> B (singleInstance) -> C藕赞,完全退出后,再次啟動卖局,首先打開的是B斧蜕。
11、View的繪制流程
自定義控件:
1吼驶、組合控件惩激。這種自定義控件不需要我們自己繪制,而是使用原生控件組合成的新控件蟹演。如標(biāo)題欄风钻。
2、繼承原有的控件酒请。這種自定義控件在原生控件提供的方法外骡技,可以自己添加一些方法。如制作圓角羞反,圓形圖片布朦。
3、完全自定義控件:這個View上所展現(xiàn)的內(nèi)容全部都是我們自己繪制出來的昼窗。比如說制作水波紋進(jìn)度條是趴。
View的繪制流程:OnMeasure()——>OnLayout()——>OnDraw()
第一步:OnMeasure():測量視圖大小。從頂層父View到子View遞歸調(diào)用measure方法澄惊,measure方法又回調(diào)OnMeasure唆途。
第二步:OnLayout():確定View位置,進(jìn)行頁面布局掸驱。從頂層父View向子View的遞歸調(diào)用view.layout方法的過程肛搬,即父View根據(jù)上一步measure子View所得到的布局大小和布局參數(shù),將子View放在合適的位置上毕贼。
第三步:OnDraw():繪制視圖温赔。
ViewRoot創(chuàng)建一個Canvas對象,然后調(diào)用OnDraw()鬼癣。
六個步驟:
①陶贼、繪制視圖的背景啤贩;
②、保存畫布的圖層(Layer)拜秧;
③瓜晤、繪制View的內(nèi)容;
④腹纳、繪制View子視圖,如果沒有就不用驱犹;
⑤嘲恍、還原圖層(Layer);
⑥雄驹、繪制滾動條佃牛。
12、View医舆,ViewGroup事件分發(fā)
Touch事件分發(fā)中只有兩個主角:ViewGroup和View俘侠。
ViewGroup
包含onInterceptTouchEvent、dispatchTouchEvent蔬将、onTouchEvent三個相關(guān)事件爷速。
View
包含dispatchTouchEvent、onTouchEvent兩個相關(guān)事件霞怀。
其中ViewGroup又繼承于View惫东。
2.ViewGroup和View組成了一個樹狀結(jié)構(gòu),根節(jié)點(diǎn)為Activity內(nèi)部包含的一個ViewGroup毙石。
3.觸摸事件由Action_Down廉沮、Action_Move、Aciton_UP組成徐矩,其中一次完整的觸摸事件中滞时,Down和Up都只有一個,Move有若干個滤灯,可以為0個坪稽。
4.當(dāng)Acitivty接收到Touch事件時(shí),將遍歷子View進(jìn)行Down事件的分發(fā)力喷。ViewGroup的遍歷可以看成是遞歸的刽漂。分發(fā)的目的是為了找到真正要處理本次完整觸摸事件的View,這個View會在onTouchuEvent結(jié)果返回true弟孟。
5.當(dāng)某個子View返回true時(shí)贝咙,會中止Down事件的分發(fā),同時(shí)在ViewGroup中記錄該子View拂募。接下去的Move和Up事件將由該子View直接進(jìn)行處理庭猩。由于子View是保存在ViewGroup中的窟她,多層ViewGroup的節(jié)點(diǎn)結(jié)構(gòu)時(shí),上級ViewGroup保存的會是真實(shí)處理事件的View所在的ViewGroup對象:如ViewGroup0-ViewGroup1-TextView的結(jié)構(gòu)中蔼水,TextView返回了true震糖,它將被保存在ViewGroup1中,而ViewGroup1也會返回true趴腋,被保存在ViewGroup0中吊说。當(dāng)Move和UP事件來時(shí),會先從ViewGroup0傳遞至ViewGroup1优炬,再由ViewGroup1傳遞至TextView颁井。
6.當(dāng)ViewGroup中所有子View都不捕獲Down事件時(shí),將觸發(fā)ViewGroup自身的onTouch事件蠢护。觸發(fā)的方式是調(diào)用super.dispatchTouchEvent函數(shù)雅宾,即父類View的dispatchTouchEvent方法。在所有子View都不處理的情況下葵硕,觸發(fā)Acitivity的onTouchEvent方法眉抬。
7.onInterceptTouchEvent有兩個作用:
1.攔截Down事件的分發(fā)。
2.中止Up和Move事件向目標(biāo)View傳遞懈凹,使得目標(biāo)View所在的ViewGroup捕獲Up和Move事件蜀变。
13、保存Activity狀態(tài)
onSaveInstanceState(Bundle)會在activity轉(zhuǎn)入后臺狀態(tài)之前被調(diào)用蘸劈,也就是onStop()方法之前昏苏,onPause方法之后被調(diào)用;
14威沫、Android中的幾種動畫
幀動畫:
指通過指定每一幀的圖片和播放時(shí)間贤惯,有序的進(jìn)行播放而形成動畫效果,比如想聽的律動條棒掠。
補(bǔ)間動畫:
指通過指定View的初始狀態(tài)孵构、變化時(shí)間、方式烟很,通過一系列的算法去進(jìn)行圖形變換颈墅,從而形成動畫效果,主要有Alpha雾袱、Scale恤筛、Translate、Rotate四種效果芹橡。
注意:只是在視圖層實(shí)現(xiàn)了動畫效果毒坛,并沒有真正改變View的屬性,比如滑動列表,改變標(biāo)題欄的透明度煎殷。
屬性動畫:
在Android3.0的時(shí)候才支持屯伞,通過不斷的改變View的屬性,不斷的重繪而形成動畫效果豪直。相比于視圖動畫劣摇,View的屬性是真正改變了。比如view的旋轉(zhuǎn)弓乙,放大末融,縮小。
15暇韧、Android中跨進(jìn)程通訊的幾種方式
Android跨進(jìn)程通信滑潘,像intent,contentProvider,廣播锨咙,service都可以跨進(jìn)程通信。
intent:
這種跨進(jìn)程方式并不是訪問內(nèi)存的形式追逮,它需要傳遞一個uri,比如說打電話酪刀。
contentProvider:
這種形式,是使用數(shù)據(jù)共享的形式進(jìn)行數(shù)據(jù)共享钮孵。
service:
遠(yuǎn)程服務(wù)骂倘,比如aidl
廣播:
廣播 包含靜態(tài)廣播,動態(tài)廣播巴席。
16历涝、AIDL理解
此處延伸:簡述Binder
AIDL:
每一個進(jìn)程都有自己的Dalvik VM實(shí)例,都有自己的一塊獨(dú)立的內(nèi)存漾唉,都在自己的內(nèi)存上存儲自己的數(shù)據(jù)荧库,執(zhí)行著自己的操作,都在自己的那片狹小的空間里過完自己的一生赵刑。而aidl就類似與兩個進(jìn)程之間的橋梁分衫,使得兩個進(jìn)程之間可以進(jìn)行數(shù)據(jù)的傳輸,跨進(jìn)程通信有多種選擇般此,比如BroadcastReceiver , Messenger等蚪战,但是 BroadcastReceiver占用的系統(tǒng)資源比較多,如果是頻繁的跨進(jìn)程通信的話顯然是不可取的铐懊;Messenger進(jìn)行跨進(jìn)程通信時(shí)請求隊(duì)列是同步進(jìn)行的邀桑,無法并發(fā)執(zhí)行。
Binder機(jī)制簡單理解:
在Android系統(tǒng)的Binder機(jī)制中科乎,是有Client,Service,ServiceManager,Binder驅(qū)動程序組成的壁畸,其中Client,service喜喂,Service Manager運(yùn)行在用戶空間瓤摧,Binder驅(qū)動程序是運(yùn)行在內(nèi)核空間的竿裂。而Binder就是把這4種組件粘合在一塊的粘合劑,其中核心的組件就是Binder驅(qū)動程序照弥,Service Manager提供輔助管理的功能腻异,而Client和Service正是在Binder驅(qū)動程序和Service Manager提供的基礎(chǔ)設(shè)施上實(shí)現(xiàn)C/S 之間的通信。其中Binder驅(qū)動程序提供設(shè)備文件/dev/binder與用戶控件進(jìn)行交互这揣,
Client悔常、Service,Service Manager通過open和ioctl文件操作相應(yīng)的方法與Binder驅(qū)動程序進(jìn)行通信给赞。而Client和Service之間的進(jìn)程間通信是通過Binder驅(qū)動程序間接實(shí)現(xiàn)的机打。而Binder Manager是一個守護(hù)進(jìn)程,用來管理Service片迅,并向Client提供查詢Service接口的能力残邀。
17、Handler的原理
Android中主線程是不能進(jìn)行耗時(shí)操作的柑蛇,子線程是不能進(jìn)行更新UI的芥挣。所以就有了handler,它的作用就是實(shí)現(xiàn)線程之間的通信耻台。
handler整個流程中空免,主要有四個對象,
handler盆耽,Message,MessageQueue,Looper蹋砚。當(dāng)應(yīng)用創(chuàng)建的時(shí)候,就會在主線程中創(chuàng)建handler對象摄杂,
我們通過要傳送的消息保存到Message中坝咐,handler通過調(diào)用sendMessage方法將Message發(fā)送到MessageQueue中,Looper對象就會不斷的調(diào)用loop()方法
不斷的從MessageQueue中取出Message交給handler進(jìn)行處理析恢。從而實(shí)現(xiàn)線程之間的通信畅厢。
18、Binder機(jī)制原理
在Android系統(tǒng)的Binder機(jī)制中氮昧,是有Client,Service,ServiceManager,Binder驅(qū)動程序組成的框杜,其中Client,service袖肥,Service Manager運(yùn)行在用戶空間咪辱,Binder驅(qū)動程序是運(yùn)行在內(nèi)核空間的。而Binder就是把這4種組件粘合在一塊的粘合劑椎组,其中核心的組件就是Binder驅(qū)動程序油狂,Service Manager提供輔助管理的功能,而Client和Service正是在Binder驅(qū)動程序和Service Manager提供的基礎(chǔ)設(shè)施上實(shí)現(xiàn)C/S之間的通信。其中Binder驅(qū)動程序提供設(shè)備文件/dev/binder與用戶控件進(jìn)行交互专筷,Client弱贼、Service,Service Manager通過open和ioctl文件操作相應(yīng)的方法與Binder驅(qū)動程序進(jìn)行通信磷蛹。而Client和Service之間的進(jìn)程間通信是通過Binder驅(qū)動程序間接實(shí)現(xiàn)的吮旅。而Binder Manager是一個守護(hù)進(jìn)程,用來管理Service味咳,并向Client提供查詢Service接口的能力庇勃。
19、熱修復(fù)的原理
我們知道Java虛擬機(jī) —— JVM是加載類的class文件的槽驶,而Android虛擬機(jī)——Dalvik/ART VM是加載類的dex文件责嚷,而他們加載類的時(shí)候都需要ClassLoader,ClassLoader有一個子BaseDexClassLoader,而BaseDexClassLoader下有一個數(shù)組——DexPathList掂铐,是用來存放dex文件罕拂,當(dāng)BaseDexClassLoader通過調(diào)用findClass方法時(shí),實(shí)際上就是遍歷數(shù)組全陨,找到相應(yīng)的dex文件聂受,找到,則直接將它return烤镐。而熱修復(fù)的解決方法就是將新的dex添加到該集合中,并且是在舊的dex的前面棍鳖,所以就會優(yōu)先被取出來并且return返回炮叶。
20、Android內(nèi)存泄露及管理
(1)內(nèi)存溢出(OOM)和內(nèi)存泄露(對象無法被回收)的區(qū)別渡处。
(2)引起內(nèi)存泄露的原因
(3) 內(nèi)存泄露檢測工具 ------>LeakCanary
內(nèi)存溢出out of memory:
是指程序在申請內(nèi)存時(shí)镜悉,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory医瘫;
比如申請了一個integer,但給它存了long才能存下的數(shù)侣肄,那就是內(nèi)存溢出。內(nèi)存溢出通俗的講就是內(nèi)存不夠用醇份。
內(nèi)存泄露memory leak:
是指程序在申請內(nèi)存后稼锅,無法釋放已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略僚纷,但內(nèi)存泄露堆積后果很嚴(yán)重矩距,無論多少內(nèi)存,遲早會被占光
內(nèi)存泄露原因:
一、Handler 引起的內(nèi)存泄漏怖竭。
解決:將Handler聲明為靜態(tài)內(nèi)部類锥债,就不會持有外部類SecondActivity的引用,其生命周期就和外部類無關(guān),
如果Handler里面需要context的話哮肚,可以通過弱引用方式引用外部類
二登夫、單例模式引起的內(nèi)存泄漏。
解決:Context是ApplicationContext允趟,由于ApplicationContext的生命周期是和app一致的恼策,不會導(dǎo)致內(nèi)存泄漏
三、非靜態(tài)內(nèi)部類創(chuàng)建靜態(tài)實(shí)例引起的內(nèi)存泄漏拼窥。
解決:把內(nèi)部類修改為靜態(tài)的就可以避免內(nèi)存泄漏了
四戏蔑、非靜態(tài)匿名內(nèi)部類引起的內(nèi)存泄漏。
解決:將匿名內(nèi)部類設(shè)置為靜態(tài)的鲁纠。
五总棵、注冊/反注冊未成對使用引起的內(nèi)存泄漏。
注冊廣播接受器改含、EventBus等情龄,記得解綁。
六捍壤、資源對象沒有關(guān)閉引起的內(nèi)存泄漏骤视。
在這些資源不使用的時(shí)候,記得調(diào)用相應(yīng)的類似close()鹃觉、destroy()专酗、recycler()、release()等方法釋放盗扇。
七祷肯、集合對象沒有及時(shí)清理引起的內(nèi)存泄漏。
通常會把一些對象裝入到集合中疗隶,當(dāng)不使用的時(shí)候一定要記得及時(shí)清理集合佑笋,讓相關(guān)對象不再被引用。
21斑鼻、Fragment與Fragment蒋纬、Activity通信的方式
1.直接在一個Fragment中調(diào)用另外一個Fragment中的方法
2.使用接口回調(diào)
3.使用廣播
4.Fragment直接調(diào)用Activity中的public方法
22、Android UI適配
字體使用sp,
dp坚弱,多使用match_parent蜀备,wrap_content,weight
圖片資源荒叶,不同圖片的的分辨率琼掠,放在相應(yīng)的文件夾下可使用百分比代替。
23停撞、app優(yōu)化
app優(yōu)化:
工具:Hierarchy Viewer 分析布局
工具:TraceView測試分析耗時(shí)
App啟動優(yōu)化
布局優(yōu)化
響應(yīng)優(yōu)化
內(nèi)存優(yōu)化
電池使用優(yōu)化
網(wǎng)絡(luò)優(yōu)化
App啟動的方式有三種:
冷啟動:
App沒有啟動過或App進(jìn)程被killed, 系統(tǒng)中不存在該App進(jìn)程, 此時(shí)啟動App即為冷啟動瓷蛙。
熱啟動:
熱啟動意味著你的App進(jìn)程只是處于后臺, 系統(tǒng)只是將其從后臺帶到前臺, 展示給用戶悼瓮。
介于冷啟動和熱啟動之間,
一般來說在以下兩種情況下發(fā)生:
(1)用戶back退出了App, 然后又啟動.
App進(jìn)程可能還在運(yùn)行, 但是activity需要重建。
(2)用戶退出App后, 系統(tǒng)可能由于內(nèi)存原因?qū)pp殺死, 進(jìn)程和activity都需要重啟, 但是可以在onCreate中將被動殺死鎖保存的狀態(tài)(saved instance state)恢復(fù)艰猬。
啟動優(yōu)化:
Application的onCreate(特別是第三方SDK初始化)横堡,首屏Activity的渲染都不要進(jìn)行耗時(shí)操作,如果有冠桃,就可以放到子線程或者IntentService中命贴。
布局優(yōu)化
盡量不要過于復(fù)雜的嵌套∈程可以使用<include>胸蛛,<merge>,<ViewStub>
響應(yīng)優(yōu)化
Android系統(tǒng)每隔16ms會發(fā)出VSYNC信號重繪我們的界面(Activity)樱报。
頁面卡頓的原因:
(1)過于復(fù)雜的布局.
(2)UI線程的復(fù)雜運(yùn)算
(3)頻繁的GC
導(dǎo)致頻繁GC有兩個原因:
1葬项、內(nèi)存抖動, 即大量的對象被創(chuàng)建又在短時(shí)間內(nèi)馬上被釋放.
2、瞬間產(chǎn)生大量的對象會嚴(yán)重占用內(nèi)存區(qū)域迹蛤。
電池使用優(yōu)化(
工具:Batterystats & bugreport
(1)優(yōu)化網(wǎng)絡(luò)請求
(2)定位中使用GPS, 請記得及時(shí)關(guān)閉
網(wǎng)絡(luò)優(yōu)化
網(wǎng)絡(luò)連接對用戶的影響:流量,電量,用戶等待,可在Android studio下方logcat旁邊那個工具Network Monitor檢測
API設(shè)計(jì):
App與Server之間的API設(shè)計(jì)要考慮網(wǎng)絡(luò)請求的頻次, 資源的狀態(tài)等. 以便App可以以較少的請求來完成業(yè)務(wù)需求和界面的展示.
Gzip壓縮:
使用Gzip來壓縮request和response, 減少傳輸數(shù)據(jù)量, 從而減少流量消耗.
圖片的Size:
可以在獲取圖片時(shí)告知服務(wù)器需要的圖片的寬高, 以便服務(wù)器給出合適的圖片, 避免浪費(fèi).
網(wǎng)絡(luò)緩存:
適當(dāng)?shù)木彺? 既可以讓我們的應(yīng)用看起來更快, 也能避免一些不必要的流量消耗.
24民珍、圖片優(yōu)化
(1)對圖片本身進(jìn)行操作。
盡量不要使用setImageBitmap盗飒、setImageResource嚷量、BitmapFactory.decodeResource來設(shè)置一張大圖,因?yàn)檫@些方法在完成decode后逆趣,最終都是通過 java 層的 createBitmap 來完成的蝶溶,需要消耗更多內(nèi)存.
(2)圖片進(jìn)行縮放的比例,SDK中建議其值是2的指數(shù)值,值越大會導(dǎo)致圖片不清晰宣渗。
(3)不用的圖片記得調(diào)用圖片的recycle()方法
25抖所、HybridApp WebView和JS交互
Android與JS通過WebView互相調(diào)用方法,實(shí)際上是:
Android去調(diào)用JS的代碼
通過WebView的loadUrl(),使用該方法比較簡潔落包,方便。但是效率比較低摊唇,獲取返回值比較困難咐蝇。
通過WebView的evaluateJavascript(),該方法效率高,但是4.4以上的版本才支持巷查,4.4以下版本不支持有序。所以建議兩者混合使用。
JS去調(diào)用Android的代碼
通過WebView的addJavascriptInterface()進(jìn)行對象映射 岛请,該方法使用簡單旭寿,僅將Android對象和JS對象映射即可,但是存在比較大的漏洞崇败。
漏洞產(chǎn)生原因是:當(dāng)JS拿到Android這個對象后盅称,就可以調(diào)用這個Android對象中所有的方法肩祥,包括系統(tǒng)類(java.lang.Runtime 類),從而進(jìn)行任意代碼執(zhí)行缩膝。
解決方法:
(1)Google 在Android 4.2版本中規(guī)定對被調(diào)用的函數(shù)以 @JavascriptInterface進(jìn)行注解從而避免漏洞攻擊混狠。
(2)在Android 4.2版本之前采用攔截prompt()進(jìn)行漏洞修復(fù)。
通過 WebViewClient的shouldOverrideUrlLoading ()方法回調(diào)攔截url 疾层。
這種方式的優(yōu)點(diǎn):
不存在方式1的漏洞将饺;
缺點(diǎn):JS獲取Android方法的返回值復(fù)雜。(ios主要用的是這個方式)
(1)Android通過 WebViewClient 的回調(diào)方法shouldOverrideUrlLoading ()攔截 url
(2)解析該url的協(xié)議
(3)如果檢測到是預(yù)先約定好的協(xié)議痛黎,就調(diào)用相應(yīng)方法
通過 WebChromeClient 的onJsAlert()予弧、onJsConfirm()、onJsPrompt()方法回調(diào)攔截JS對話框alert()湖饱、confirm()掖蛤、prompt() 消息
這種方式的優(yōu)點(diǎn):不存在方式1的漏洞;缺點(diǎn):JS獲取Android方法的返回值復(fù)雜琉历。
26坠七、JAVA GC原理
垃圾收集算法的核心思想是:
對虛擬機(jī)可用內(nèi)存空間,即堆空間中的對象進(jìn)行識別旗笔,如果對象正在被引用彪置,那么稱其為存活對象,反之蝇恶,如果對象不再被引用拳魁,則為垃圾對象,可以回收其占據(jù)的空間撮弧,用于再分配潘懊。垃圾收集算法的選擇和垃圾收集系統(tǒng)參數(shù)的合理調(diào)節(jié)直接影響著系統(tǒng)性能。
27贿衍、ANR
ANR全名Application Not Responding, 也就是"應(yīng)用無響應(yīng)". 當(dāng)操作在一段時(shí)間內(nèi)系統(tǒng)無法處理時(shí), 系統(tǒng)層面會彈出上圖那樣的ANR對話框.
產(chǎn)生原因:
(1)5s內(nèi)無法響應(yīng)用戶輸入事件(例如鍵盤輸入, 觸摸屏幕等).
(2)BroadcastReceiver在10s內(nèi)無法結(jié)束
(3)Service 20s內(nèi)無法結(jié)束(低概率)
解決方式:
(1)不要在主線程中做耗時(shí)的操作授舟,而應(yīng)放在子線程中來實(shí)現(xiàn)。如onCreate()和onResume()里盡可能少的去做創(chuàng)建操作贸辈。
(2)應(yīng)用程序應(yīng)該避免在BroadcastReceiver里做耗時(shí)的操作或計(jì)算释树。
(3)避免在Intent Receiver里啟動一個Activity,因?yàn)樗鼤?chuàng)建一個新的畫面擎淤,并從當(dāng)前用戶正在運(yùn)行的程序上搶奪焦點(diǎn)奢啥。
(4)service是運(yùn)行在主線程的,所以在service中做耗時(shí)操作嘴拢,必須要放在子線程中桩盲。
28、設(shè)計(jì)模式
此處延伸:Double Check的寫法被要求寫出來席吴。
單例模式:分為惡漢式和懶漢式
惡漢式:
public class Singleton
{
private static Singleton instance = new Singleton();
public static Singleton getInstance()
{
return instance ;
}
}
懶漢式:
public class Singleton02
{
private static Singleton02 instance;
public static Singleton02 getInstance()
{
if (instance == null)
{
synchronized (Singleton02.class)
{
if (instance == null)
{
instance = new Singleton02();
}
}
}
return instance;
}
}
29赌结、Xutils, OKhttp, Volley, Retrofit對比(網(wǎng)絡(luò)框架方面)
Xutils
這個框架非常全面捞蛋,可以進(jìn)行網(wǎng)絡(luò)請求,可以進(jìn)行圖片加載處理姑曙,可以數(shù)據(jù)儲存襟交,還可以對view進(jìn)行注解,使用這個框架非常方便伤靠,但是缺點(diǎn)也是非常明顯的捣域,使用這個項(xiàng)目,會導(dǎo)致項(xiàng)目對這個框架依賴非常的嚴(yán)重宴合,一旦這個框架出現(xiàn)問題焕梅,那么對項(xiàng)目來說影響非常大的。卦洽、
OKhttp:
Android開發(fā)中是可以直接使用現(xiàn)成的api進(jìn)行網(wǎng)絡(luò)請求的贞言。就是使用HttpClient,HttpUrlConnection進(jìn)行操作。okhttp針對Java和Android程序阀蒂,封裝的一個高性能的http請求庫该窗,支持同步,異步蚤霞,而且okhttp又封裝了線程池酗失,封裝了數(shù)據(jù)轉(zhuǎn)換,封裝了參數(shù)的使用昧绣,錯誤處理等规肴。API使用起來更加的方便。但是我們在項(xiàng)目中使用的時(shí)候仍然需要自己在做一層封裝夜畴,這樣才能使用的更加的順手拖刃。
Volley:
Volley是Google官方出的一套小而巧的異步請求庫,該框架封裝的擴(kuò)展性很強(qiáng)贪绘,支持HttpClient兑牡、HttpUrlConnection, 甚至支持OkHttp税灌,而且Volley里面也封裝了ImageLoader均函,所以如果你愿意你甚至不需要使用圖片加載框架,不過這塊功能沒有一些專門的圖片加載框架強(qiáng)大垄琐,對于簡單的需求可以使用贴届,稍復(fù)雜點(diǎn)的需求還是需要用到專門的圖片加載框架征讲。
Volley也有缺陷,比如不支持post大數(shù)據(jù)烟号,所以不適合上傳文件坯认。不過Volley設(shè)計(jì)的初衷本身也就是為頻繁的翻擒、數(shù)據(jù)量小的網(wǎng)絡(luò)請求而生氓涣。
Retrofit:
Retrofit是Square公司出品的默認(rèn)基于OkHttp封裝的一套RESTful網(wǎng)絡(luò)請求框架,RESTful是目前流行的一套api設(shè)計(jì)的風(fēng)格陋气, 并不是標(biāo)準(zhǔn)劳吠。
Retrofit的封裝可以說是很強(qiáng)大,里面涉及到一堆的設(shè)計(jì)模式,可以通過注解直接配置請求巩趁,可以使用不同的http客戶端痒玩,雖然默認(rèn)是用http ,可以使用不同Json Converter 來序列化數(shù)據(jù)议慰,同時(shí)提供對RxJava的支持蠢古,使用Retrofit + OkHttp + RxJava + Dagger2可以說是目前比較潮的一套框架,但是需要有比較高的門檻别凹。
Volley VS OkHttp:
Volley的優(yōu)勢在于封裝的更好草讶,而使用OkHttp你需要有足夠的能力再進(jìn)行一次封裝。而OkHttp的優(yōu)勢在于性能更高炉菲,因?yàn)?OkHttp基于NIO和Okio 堕战,所以性能上要比Volley更快。IO和NIO這兩個都是Java中的概念拍霜,如果我從硬盤讀取數(shù)據(jù)嘱丢,第一種方式就是程序一直等,數(shù)據(jù)讀完后才能繼續(xù)操作這種是最簡單的也叫阻塞式IO,還有一種是你讀你的,程序接著往下執(zhí)行沉御,等數(shù)據(jù)處理完你再來通知我屿讽,然后再處理回調(diào)。而第二種就是 NIO 的方式吠裆,非阻塞式伐谈, 所以NIO當(dāng)然要比IO的性能要好了,而 Okio是Square公司基于IO和NIO基礎(chǔ)上做的一個更簡單、高效處理數(shù)據(jù)流的一個庫试疙。理論上如果Volley和OkHttp對比的話诵棵,更傾向于使用Volley,因?yàn)閂olley內(nèi)部同樣支持使用OkHttp,這點(diǎn)OkHttp的性能優(yōu)勢就沒了祝旷, 而且 Volley 本身封裝的也更易用履澳,擴(kuò)展性更好些。
OkHttp VS Retrofit
毫無疑問怀跛,Retrofit 默認(rèn)是基于OkHttp 而做的封裝距贷,這點(diǎn)來說沒有可比性,肯定首選Retrofit吻谋。
Volley VS Retrofit
這兩個庫都做了不錯的封裝忠蝗,但Retrofit解耦的更徹底,尤其Retrofit2.0出來,Jake對之前1.0設(shè)計(jì)不合理的地方做了大量重構(gòu)漓拾, 職責(zé)更細(xì)分阁最,而且Retrofit默認(rèn)使用OkHttp,性能上也要比Volley占優(yōu)勢戒祠,再有如果你的項(xiàng)目如果采用了RxJava,那更該使用Retrofit 速种。所以這兩個庫相比姜盈,Retrofit更有優(yōu)勢,在能掌握兩個框架的前提下該優(yōu)先使用 Retrofit配阵。但是Retrofit門檻要比Volley稍高些馏颂,要理解他的原理,各種用法棋傍,想徹底搞明白還是需要花些功夫的饱亮,如果你對它一知半解,那還是建議在商業(yè)項(xiàng)目使用Volley吧舍沙。
30近上、MVP,MVC拂铡,MVVM
此處延伸:手寫mvp例子壹无,與mvc之間的區(qū)別,mvp的優(yōu)勢
MVP模式
對應(yīng)著
Model:業(yè)務(wù)邏輯和實(shí)體模型,
view:對應(yīng)著activity感帅,負(fù)責(zé)View的繪制以及與用戶交互,
Presenter:負(fù)責(zé)View和Model之間的交互,
MVP模式是在MVC模式的基礎(chǔ)上斗锭,將Model與View徹底分離使得項(xiàng)目的耦合性更低,在Mvc中項(xiàng)目中的activity對應(yīng)著mvc中的C--Controllor,而項(xiàng)目中的邏輯處理都是在這個C中處理失球,同時(shí)View與Model之間的交互岖是,也是也就是說,mvc中所有的邏輯交互和用戶交互实苞,都是放在Controllor中豺撑,也就是activity中。View和model是可以直接通信的黔牵。而MVP模式則是分離的更加徹底聪轿,分工更加明確Model業(yè)務(wù)邏輯和實(shí)體模型,view負(fù)責(zé)與用戶交互猾浦,Presenter 負(fù)責(zé)完成View于Model間的交互陆错,MVP和MVC最大的區(qū)別是MVC中是允許Model和View進(jìn)行交互的,而MVP中很明顯金赦,Model與View之間的交互由Presenter完成音瓷。還有一點(diǎn)就是Presenter與View之間的交互是通過接口的
31、JNI
(1)安裝和下載Cygwin夹抗,下載 Android NDK
(2)在ndk項(xiàng)目中JNI接口的設(shè)計(jì)
(3)使用C/C++實(shí)現(xiàn)本地方法
(4)JNI生成動態(tài)鏈接庫.so文件
(5)將動態(tài)鏈接庫復(fù)制到j(luò)ava工程绳慎,在java工程中調(diào)用,運(yùn)行java工程即可
32、RecyclerView和ListView的區(qū)別
RecyclerView可以完成ListView,GridView的效果偷线,還可以完成瀑布流的效果。同時(shí)還可以設(shè)置列表的滾動方向(垂直或者水平)沽甥;
RecyclerView中view的復(fù)用不需要開發(fā)者自己寫代碼声邦,系統(tǒng)已經(jīng)幫封裝完成了。
RecyclerView可以進(jìn)行局部刷新摆舟。
RecyclerView提供了API來實(shí)現(xiàn)item的動畫效果亥曹。
在性能上:
如果需要頻繁的刷新數(shù)據(jù),需要添加動畫恨诱,則RecyclerView有較大的優(yōu)勢媳瞪。
如果只是作為列表展示,則兩者區(qū)別并不是很大照宝。
33蛇受、Universal-ImageLoader,Picasso厕鹃,F(xiàn)resco兢仰,Glide對比
Fresco
是 Facebook推出的開源圖片緩存工具,主要特點(diǎn)包括:兩個內(nèi)存緩存加上 Native 緩存構(gòu)成了三級緩存剂碴,
優(yōu)點(diǎn):
圖片存儲在安卓系統(tǒng)的匿名共享內(nèi)存, 而不是虛擬機(jī)的堆內(nèi)存中, 圖片的中間緩沖數(shù)據(jù)也存放在本地堆內(nèi)存, 所以, 應(yīng)用程序有更多的內(nèi)存使用, 不會因?yàn)閳D片加載而導(dǎo)致oom, 同時(shí)也減少垃圾回收器頻繁調(diào)用回收Bitmap導(dǎo)致的界面卡頓, 性能更高把将。
漸進(jìn)式加載 JPEG 圖片, 支持圖片從模糊到清晰加載。
圖片可以以任意的中心點(diǎn)顯示在 ImageView, 而不僅僅是圖片的中心忆矛。
JPEG圖片改變大小也是在native進(jìn)行的, 不是在虛擬機(jī)的堆內(nèi)存, 同樣減少 OOM察蹲。
很好的支持GIF圖片的顯示。
缺點(diǎn):
框架較大, 影響 Apk 體積
使用較繁瑣
Universal-ImageLoader:
估計(jì)由于HttpClient被Google放棄催训,作者就放棄維護(hù)這個框架
優(yōu)點(diǎn):
1.支持下載進(jìn)度監(jiān)聽
2.可以在View 滾動中暫停圖片加載洽议,通過 PauseOnScrollListener 接口可以在View 滾動中暫停圖片加載。
3.默認(rèn)實(shí)現(xiàn)多種內(nèi)存緩存算法 這幾個圖片緩存都可以配置緩存算法漫拭,不過ImageLoader默認(rèn)實(shí)現(xiàn)了較多緩存算法绞铃,如 Size最大先刪除、使用最少先刪除嫂侍、最近最少使用儿捧、先進(jìn)先刪除、時(shí)間最長先刪除等挑宠。
4.支持本地緩存文件名規(guī)則定義
Picasso 優(yōu)點(diǎn)
自帶統(tǒng)計(jì)監(jiān)控功能菲盾。支持圖片緩存使用的監(jiān)控,包括緩存命中率各淀、已使用內(nèi)存大小懒鉴、節(jié)省的流量等。
2.支持優(yōu)先級處理。每次任務(wù)調(diào)度前會選擇優(yōu)先級高的任務(wù)临谱,比如 App頁面中Banner的優(yōu)先級高于Icon時(shí)就很適用璃俗。
3.支持延遲到圖片尺寸計(jì)算完成加載
4.支持飛行模式、并發(fā)線程數(shù)根據(jù)網(wǎng)絡(luò)類型而變悉默。 手機(jī)切換到飛行模式或網(wǎng)絡(luò)類型變換時(shí)會自動調(diào)整線程池最大并發(fā)數(shù)城豁,比如 wifi最大并發(fā)為4,4g 為 3抄课,3g 為 2唱星。 這里Picasso根據(jù)網(wǎng)絡(luò)類型來決定最大并發(fā)數(shù),而不是CPU核數(shù)跟磨。
5.“無”本地緩存间聊。無”本地緩存,不是說沒有本地緩存抵拘,而是 Picasso自己沒有實(shí)現(xiàn)哎榴,交給了Square的另外一個網(wǎng)絡(luò)庫 okhttp 去實(shí)現(xiàn),這樣的好處是可以通過請求 Response Header中的 Cache-Control 及 Expired 控制圖片的過期時(shí)間僵蛛。
Glide 優(yōu)點(diǎn)
不僅僅可以進(jìn)行圖片緩存還可以緩存媒體文件叹话。Glide 不僅是一個圖片緩存,它支持 Gif墩瞳、WebP驼壶、縮略圖。甚至是 Video喉酌,所以更該當(dāng)做一個媒體緩存热凹。
支持優(yōu)先級處理。
與 Activity/Fragment 生命周期一致泪电,支持trimMemory般妙。Glide 對每個 context都保持一個RequestManager,通過 FragmentTransaction 保持與Activity/Fragment生命周期一致相速,并且有對應(yīng)的 trimMemory接口實(shí)現(xiàn)可供調(diào)用碟渺。
支持okhttp、Volley突诬。Glide 默認(rèn)通過 UrlConnection獲取數(shù)據(jù)苫拍,可以配合okhttp或是 Volley 使用。實(shí)際 ImageLoader旺隙、Picasso 也都支持 okhttp绒极、Volley。
內(nèi)存友好蔬捷。Glide的內(nèi)存緩存有個active 的設(shè)計(jì)垄提,從內(nèi)存緩存中取數(shù)據(jù)時(shí)榔袋,不像一般的實(shí)現(xiàn)用 get,而是用 remove铡俐,再將這個緩存數(shù)據(jù)放到一個value為軟引用的 activeResources map 中凰兑,并計(jì)數(shù)引用數(shù),在圖片加載完成后進(jìn)行判斷审丘,如果引用計(jì)數(shù)為空則回收掉吏够。內(nèi)存緩存更小圖片,Glide 以 url备恤、view_width、view_height锦秒、屏幕的分辨率等做為聯(lián)合 key露泊,將處理后的圖片緩存在內(nèi)存緩存中,而不是原始圖片以節(jié)省大小與 Activity/Fragment 生命周期一致旅择,支持 trimMemory惭笑。圖片默認(rèn)使用默認(rèn) RGB_565 而不是 ARGB_888,雖然清晰度差些生真,但圖片更小沉噩,也可配置到 ARGB_888。