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