Activity的啟動(dòng)模式和應(yīng)用場景
standard: 默認(rèn)模式,一個(gè)activity實(shí)例對(duì)應(yīng)一個(gè)棧中對(duì)象,意味著可重復(fù)添加同一個(gè)activity入棧;大部分普通場景
singleTop: 棧頂單例模式,當(dāng)activity處于棧頂時(shí),再次創(chuàng)建同一個(gè)activity的實(shí)例時(shí),會(huì)復(fù)用棧頂activity,不會(huì)創(chuàng)建新的實(shí)例;activity不處于棧頂?shù)臅r(shí)候與standard啟動(dòng)模式相同;適合防止連續(xù)點(diǎn)擊造成創(chuàng)建多次activity的情景
singleTask: 棧中單例模式,如果activity已存在于棧中,再次創(chuàng)建同一個(gè)activity實(shí)例時(shí),會(huì)將該activity推到棧頂并且將該activity上的其他activity實(shí)例出棧(銷毀)
singleInstance: 新建棧單例模式,不管是否存在相同的activity實(shí)例,創(chuàng)建該activity時(shí)都會(huì)新建一個(gè)新的棧并將該activity放入新建的棧中
Touch事件傳遞機(jī)制
Touch事件的傳遞分成兩個(gè)過程:
- 分發(fā)和處理
當(dāng)點(diǎn)擊發(fā)生時(shí),會(huì)父布局最先響應(yīng),調(diào)用分發(fā)方法向子控件分發(fā)事件(其中經(jīng)過一個(gè)攔截過程,viewGroup有一個(gè)是否允許攔截的屬性,如果允許攔截并且確認(rèn)攔截的時(shí)候?qū)⒉粫?huì)向子控件分發(fā)事件),一直分發(fā)到非viewGroup的view中,結(jié)束分發(fā)過程
即事件分發(fā)的過程是由父控件到子控件的當(dāng)view分發(fā)到事件后(dispatchTouchEvent),會(huì)判斷該控件是否有設(shè)置了onTouchlistener,有且listener的的onTouch方法返回為true時(shí),該方法會(huì)返回true,否則返回onTouchEvent的返回值,返回值為true表明事件已被view消費(fèi)了,不會(huì)再傳遞到父控件處理,反之向上傳遞事件(由此可見,處理的過程是從子控件到父控件的)
也就是說,當(dāng)onTouch方法返回true時(shí),onTouchEvent是不會(huì)被調(diào)用的,也因?yàn)閛nClick方法是在performClick方法中被調(diào)用,而performClick方法是在onTouchEvent中被調(diào)用的,所以onClick方法自然也就被屏蔽掉了
如果onTouch返回false的話,就會(huì)調(diào)用onTouchEvent,onTouchEvent中會(huì)判斷該view是否可點(diǎn)擊,不可點(diǎn)擊幾乎不會(huì)做處理,但會(huì)消費(fèi)掉該action;可點(diǎn)擊的話,會(huì)在ACTION_UP的時(shí)候調(diào)用performClick(不同的action會(huì)有不同的處理邏輯);performClick會(huì)判斷onClickListener不為空時(shí)調(diào)用onClick
view繪制流程
view的繪制涉及幾個(gè)方法: onMeasure:測量view的大小,從父布局到子控件遞歸調(diào)用measure方法,measure方法調(diào)用onMeasure; onLayout:確定view在父控件中的位置
onSizeChanged: 當(dāng)控件大小改變時(shí)調(diào)用,可獲取新舊寬高 onDrawBackgound:繪制背景(不能重寫)
onDraw: 繪制內(nèi)容 onDrawForeground:繪制前景(滑動(dòng)邊緣漸變和滑動(dòng)條等)
動(dòng)畫類別
幀動(dòng)畫: 利用一張張的圖片輪播形成的動(dòng)畫
屬性動(dòng)畫: 通過控制隨時(shí)間變化的浮點(diǎn)值控制值的變化,多用于控件的屬性變化(改變控件坐標(biāo))
補(bǔ)間動(dòng)畫: 設(shè)定開始和結(jié)束的狀態(tài),中間的變化自動(dòng)補(bǔ)充,不改變控件坐標(biāo)
Binder機(jī)制
進(jìn)程的內(nèi)存空間分為兩種,一種是用戶空間,另一種是內(nèi)核控件; 普通的數(shù)據(jù)是存放在用戶空間的,也因?yàn)橛脩艨臻g是進(jìn)程獨(dú)立的不能訪問其他進(jìn)程的用戶空間,所以進(jìn)程間不能直接通信
Binder就是用于進(jìn)程間通信的機(jī)制; 雖然用戶空間不能跨進(jìn)程訪問,但是內(nèi)核空間卻可以,所以跨進(jìn)程通信時(shí),需要通過訪問共用的內(nèi)核空間實(shí)現(xiàn),Binder驅(qū)動(dòng)就是實(shí)現(xiàn)內(nèi)核空間的通信的
Android進(jìn)程間通信的實(shí)現(xiàn)方式
Binder
Socket
文件共享(如sharedPreference)
intent
contentProvider
AIDL
廣播
服務(wù)
自定義view流程
繼承view或groupView或已有原生控件
如有需要自定義屬性
在onmeasure中確定view的大小
在ondraw中畫出內(nèi)容
如有需要暴露設(shè)置屬性的方法
ANR是什么,怎么避免
ANR即Application not responsing,應(yīng)用無響應(yīng); 在Android系統(tǒng)中,activity5秒內(nèi)無響應(yīng)則出現(xiàn)ANR,廣播10秒,服務(wù)20秒
避免: 將耗時(shí)的同步操作放到子線程執(zhí)行(網(wǎng)絡(luò)請(qǐng)求,文件讀寫,海量數(shù)據(jù)處理等)
消息機(jī)制
消息機(jī)制中有四個(gè)關(guān)鍵類:Handler、Message、Looper、MessageQueue
Handler是用來輔助消息發(fā)送和處理的類; 可通過復(fù)寫handleMessage來處理 Message,通過post或postDelay來發(fā)送消息
Message是消息的載體; what屬性是消息的標(biāo)識(shí),用int值來標(biāo)記不同的消息類型,obj為消息中包含的信息,一般用于存放處理消息是要用到的數(shù)據(jù);還有一些數(shù)組和數(shù)值的屬性是一些便捷的存放數(shù)據(jù)的屬性
MessageQueue是消息的隊(duì)列; 名字雖然是隊(duì)列,但是MessageQueue是用單鏈表實(shí)現(xiàn)的,因?yàn)閱捂湵碓诓迦牒蛣h除上表現(xiàn)較好;MessageQueue使用先進(jìn)先出的原則,按序取出消息
Looper是一個(gè)不斷輪詢MessageQueue的類,會(huì)不斷取出MessageQueue中的消息; 每一個(gè)線程中只能有一個(gè)Looper;主線程的Looper在線程創(chuàng)建的時(shí)候就自動(dòng)創(chuàng)建并開始輪詢了Looper的存放使用ThreadLocal實(shí)現(xiàn),ThreadLocal用于創(chuàng)建一個(gè)線程的共享變量,當(dāng)在一個(gè)已有Looper的線程中再次創(chuàng)建Looper,會(huì)拿到相同的Looper
性能優(yōu)化
布局優(yōu)化: 盡量將減少布局的層級(jí),很少情況下使用的布局可以使用stub標(biāo)簽,使用include標(biāo)簽減少重復(fù)布局的編寫
繪制優(yōu)化: 自定義控件中的ondraw方法盡量不要做耗時(shí)操作和盡量少的初始化操作,保證繪制的流暢性
線程優(yōu)化: 多線程開發(fā)時(shí)多使用線程池對(duì)線程進(jìn)行管理,更好地復(fù)用線程以及對(duì)最大并發(fā)進(jìn)行控制
內(nèi)存泄漏優(yōu)化: handler、AsynTask、靜態(tài)變量、廣播、contentReceiver等的使用注意處理潛在的內(nèi)存泄漏問題
廣播注冊(cè)的方式與區(qū)別
靜態(tài)注冊(cè): 在清單文件中聲明廣播,這種廣播是常駐型廣播,長期占用內(nèi)存,占用CPU資源,但這種廣播可以在app不運(yùn)行的時(shí)候監(jiān)聽,例如開機(jī)廣播
動(dòng)態(tài)注冊(cè): 在Application或其他組件中用代碼動(dòng)態(tài)聲明的廣播,非常駐型廣播,廣播的生命周期和組件綁定,但要在onDestroy的時(shí)候注銷廣播,否則容易造成內(nèi)存泄漏
進(jìn)程保活,避免service死亡
進(jìn)程?;睿?可以使用AlarmManager或WorkManager定時(shí)啟動(dòng)activity,當(dāng)進(jìn)程死亡后拉起;使用前臺(tái)服務(wù)來提高進(jìn)程的優(yōu)先級(jí),提高進(jìn)程的存活率
service?;睿?設(shè)置為前臺(tái)服務(wù)提高優(yōu)先級(jí);在進(jìn)程中輪詢service是否死亡,死亡則重新啟動(dòng);在onStartCommand中返回STICKY,當(dāng)service被殺死后,系統(tǒng)會(huì)盡量復(fù)活粘性服務(wù);onDestroy時(shí)發(fā)送一個(gè)自定義廣播,收到廣播重啟service
GC
Java有自動(dòng)回收機(jī)制,即GC(Garbage Collection),當(dāng)jvm判斷一個(gè)對(duì)象已經(jīng)“無用”了,就會(huì)釋放其內(nèi)存;是否“無用”jvm依靠一種引用鏈的機(jī)制判斷(弱引用除外,弱引用無論如何都會(huì)被回收)
只要這個(gè)對(duì)象在GC Root的引用鏈中的話,這個(gè)對(duì)象就是“有用”,反之為“無用”
GC Root有如下: 正在運(yùn)行的線程、靜態(tài)變量、native中調(diào)用的方法、棧幀中的局部變量等
ML的發(fā)生就是一個(gè)對(duì)象其實(shí)已經(jīng)是無用的了,但是缺由于某種原因還存在于GC Root的引用鏈中,jvm判斷為“有用”,這時(shí)候就不會(huì)回收該對(duì)象從而發(fā)生內(nèi)存泄漏
RecyclerView和ListView的區(qū)別
RecyclerView可以實(shí)現(xiàn)ListView的顯示效果,同時(shí)也可以實(shí)現(xiàn)瀑布流的效果,也可以設(shè)置滾動(dòng)的方向; RecyclerView的item復(fù)用不用手動(dòng)實(shí)現(xiàn),已經(jīng)封裝好了
(viewHolder) RecyclerView可以實(shí)現(xiàn)局部刷新
需要使用動(dòng)畫的情況下,RecyclerView的性能比ListView好,而且RecyclerView提供了使用動(dòng)畫的API
單純顯示列表數(shù)據(jù)兩者區(qū)別不大
Glide框架的優(yōu)缺點(diǎn)
優(yōu)點(diǎn): 加載的生命周期與activity的生命周期綁定、儲(chǔ)存的圖片內(nèi)存占用較小、多媒體緩存、可以設(shè)置優(yōu)先級(jí)加載、支持okhttp和volley獲取網(wǎng)絡(luò)圖片
缺點(diǎn): 因?yàn)楦袷降膯栴},顯示的圖片清晰度不足,但可以設(shè)置不同的格式
設(shè)計(jì)模式
單例模式:
單例模式是指某個(gè)對(duì)象在全局只存在唯一的一個(gè)實(shí)例,這樣的設(shè)計(jì)模式能避免一些內(nèi)存占用較大的對(duì)象被頻繁創(chuàng)建,能在全局中提供一個(gè)唯一的實(shí)例(多用于管理類)
做法是將類構(gòu)造方法私有化,然后在類中聲明一個(gè)該類的對(duì)象并向外提供獲取該對(duì)象的方法(一般是getInstance),該方法被調(diào)用時(shí),先判斷內(nèi)部類對(duì)象是否為空,為空則創(chuàng)建一個(gè)實(shí)例賦值給該對(duì)象并返回,不為空則直接返回該對(duì)象
單例模式的實(shí)現(xiàn)方法有:枚舉實(shí)現(xiàn),單鎖式,雙鎖式,加載初始式、靜態(tài)內(nèi)部對(duì)象式
建造者模式:
建造者模式能夠?qū)?gòu)建具有復(fù)雜屬性的對(duì)象的過程變成鏈?zhǔn)秸{(diào)用,使得構(gòu)建對(duì)象更加清晰明了
做法是在對(duì)象中定義一個(gè)靜態(tài)內(nèi)部類Builder,定義一套跟外部類屬性完全相同的屬性,并定義一系列的設(shè)置方法,方法的返回都是this(實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用)。最后定義一個(gè)build方法,用Builder中的屬性構(gòu)建外部對(duì)象并返回
觀察者模式:
觀察者模式旨在響應(yīng),即被觀察者發(fā)生變化是會(huì)即時(shí)通知觀察者(可以是多個(gè)觀察者)
策略模式:
策略模式強(qiáng)調(diào)多個(gè)具有相同功能但實(shí)現(xiàn)不同的邏輯應(yīng)該講功能抽象成接口;例如同一個(gè)功能支付,卻有支付寶、微信、銀聯(lián)卡等不同的具體實(shí)現(xiàn)邏輯,這時(shí)候應(yīng)該講支付功能抽象成一個(gè)接口,不同的支付方式實(shí)現(xiàn)這個(gè)接口并定義具體的支付邏輯
好處是方便對(duì)不同實(shí)現(xiàn)邏輯的增刪改,面對(duì)接口編程,對(duì)修改關(guān)閉,對(duì)拓展開放。但只適用于程序掌握全部所有的邏輯的情況下
工廠模式:
工廠模式是一種創(chuàng)建對(duì)象的設(shè)計(jì)模式,該設(shè)計(jì)模式識(shí)具體的構(gòu)建邏輯不會(huì)暴露,相當(dāng)于你需要一臺(tái)汽車,你去工廠提車但并不需要知道這汽車是怎么造出來的
做法是定義一個(gè)接口對(duì)象(比如車),實(shí)現(xiàn)多個(gè)子類,子類里是具體的構(gòu)建方法(紅色的車、柴油車、汽油車等的具體生產(chǎn)的方法),接著創(chuàng)建一個(gè)能根據(jù)具體需要?jiǎng)?chuàng)建對(duì)象的工廠類(汽車廠),使用工廠(向工廠提要求,比如我要一臺(tái)汽油車),工廠根據(jù)要求選擇相應(yīng)的子類(汽油車的生產(chǎn)方法),構(gòu)建一個(gè)接口對(duì)象返回(工廠交付一臺(tái)車)
說了這么多,其實(shí)最重要的就是一句話,問問你自己:你現(xiàn)在所擁有的技術(shù)層次真的有信心在這家公司入職嗎?
近段時(shí)間我這里整理了一份完整的《2022年 Android 中高級(jí)面試題匯總》希望這份系統(tǒng)化的技術(shù)體系對(duì)大家有一個(gè)方向參考
有需要的同學(xué),可以順手給我點(diǎn)贊評(píng)論支持一下
內(nèi)容如果對(duì)大家有用的話,可以轉(zhuǎn)發(fā)分享一下
獲取方式:私信 發(fā)送 “進(jìn)階” 或 “面試” 即可 免費(fèi)獲取
《2022年 Android 中高級(jí)面試題匯總》
由于篇幅有限,僅展示部分內(nèi)容
第一章 Java 基礎(chǔ)
第一節(jié) 靜態(tài)內(nèi)部類和非靜態(tài)內(nèi)部類的比較
1.1 靜態(tài)內(nèi)部類和非靜態(tài)內(nèi)部類的區(qū)別
1.2 擴(kuò)展:內(nèi)部類都有哪些?
1.3 同部內(nèi)部類
1.4 匿名內(nèi)部類:是一種沒有炎名的內(nèi)部類
第二節(jié) 多態(tài)的理解與應(yīng)用
2.1 多態(tài)概述
2.2 多態(tài)中成員的持點(diǎn)
2.3 instanceof關(guān)樁字
2.4 多態(tài)的轉(zhuǎn)型
2.5 多態(tài)案例
第三節(jié) java 方法的多態(tài)性理解
3.1 什么是java的多態(tài)
3.2 遠(yuǎn)行時(shí)多態(tài)3.3代碼理解
3.4 深一點(diǎn)
3.5 再深一點(diǎn)
3.6 最后一個(gè)煉習(xí)
第四節(jié) java中接口和選承的區(qū)別
第五節(jié) 線程池的好處,詳解,單例(絕對(duì)好記)
5.1 線程池的好處
5.2 線程池的詳解
5.3 線程池的單例
第二章 Android 基礎(chǔ)
第一節(jié) Activity 知識(shí)點(diǎn)(必問)
1.1 Activity 啟動(dòng)過程全解析
1.2 啟動(dòng)模式以及使用場景
1.3 onSavelnstanceStatelJBonRestorelnstar
1.4onConfigurationChanged使用以及問題解決
第二節(jié) Fragment 知識(shí)點(diǎn)
2.1 Fragment的通信問題,新建Fragment為何不
2.2 為什么官方推薦Fragment.setArguments(B
2.3 Androidx下Fragment懶加載的新實(shí)現(xiàn)
2.4 Fragment全解析系列(一):那些年深過的
2.5 Google-Fragment 概覽
2.6 Google -與其他 Fragment 通信
第三節(jié) Service 知識(shí)點(diǎn)
3.1 Handle 知識(shí)點(diǎn)(必問)
3.2 Android 主線程阻塞處理及優(yōu)化
3.3深入聊聊Android消息機(jī)制中的消息隊(duì)列的
3.4深入理解MessageQueue
3.5 你真的懂Handler.postDelayed(的原理嗎?
3.6 Handler.postDelayed0是如何精確延遲指成
3.7 Handler 延遲消息執(zhí)行機(jī)制,會(huì)阻塞嗎?
第四節(jié)Intent知識(shí)點(diǎn)
4.1 Android 跨進(jìn)程傳遞大內(nèi)存數(shù)據(jù)
4.2 數(shù)據(jù)存健
獲取方式:私信 發(fā)送 “進(jìn)階” 或 “面試” 即可 免費(fèi)獲取
技術(shù)是無止境的,你需要對(duì)自己提交的每一行代碼、使用的每一個(gè)工具負(fù)責(zé),不斷挖掘其底層原理,才能使自己的技術(shù)升華到更高的層面
Android 架構(gòu)師之路還很漫長,與君共勉
PS:有問題歡迎指正,可以在評(píng)論區(qū)留下你的建議和感受;
歡迎大家點(diǎn)贊評(píng)論,覺得內(nèi)容可以的話,可以轉(zhuǎn)發(fā)分享一下