2021年Android面試題匯總(中級(jí))
1.跨進(jìn)程通信的幾種方式
Intent,比如撥打電話
ContentProvider數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù)
Broadcast廣播通信
AIDL通信十饥,通過接口共享數(shù)據(jù)
2.wait和 sleep 的區(qū)別
wait是Object的方法,wait是對(duì)象鎖每界,鎖定方法不讓繼續(xù)執(zhí)行日缨,當(dāng)執(zhí)行notify方法后就會(huì)繼續(xù)執(zhí)行宾毒,sleep 是Thread的方法,sleep 是使線程睡眠殿遂,讓出cpu诈铛,結(jié)束后自動(dòng)繼續(xù)執(zhí)行
3.String,StringBuffer,StringBuilder的區(qū)別
String不可改變對(duì)象,一旦創(chuàng)建就不能修改
String str="aaa";
str="bbb";
以上代碼雖然改變了str墨礁,但是執(zhí)行過程是回收str幢竹,把值賦給一個(gè)新的str
StringBuffer創(chuàng)建之后,可以去修改
StringBuilder也可修改恩静,執(zhí)行效率高于StringBuffer焕毫,不安全
當(dāng)字符賦值少使用String
字符賦值頻繁使用StringBuilder
當(dāng)多個(gè)線程同步操作數(shù)據(jù),使用StringBuffer
4.View和SurfaceView的區(qū)別
View基于主線程刷新UI驶乾,SurfaceView子線程又可以刷新UI
5.View的繪制原理
View為所有圖形控件的基類邑飒,View的繪制由3個(gè)函數(shù)完成
measure,計(jì)算視圖的大小
layout,提供視圖要顯示的位置
draw,繪制
6.簡(jiǎn)述JNI
是java和c語言之間的橋梁,由于java是一種半解釋語言级乐,可以被反編譯出來疙咸,一種重要涉及安全的代碼就使用了C編程,再者很多底層功能調(diào)用C語言都實(shí)現(xiàn)了Java沒必要重復(fù)造輪子风科,所以定義了JNI接口的實(shí)現(xiàn)
7.簡(jiǎn)述TCP撒轮,UDP,Socket
TCP是經(jīng)過3次握手贼穆,4次揮手完成一串?dāng)?shù)據(jù)的傳送
UDP是無連接的题山,知道IP地址和端口號(hào),向其發(fā)送數(shù)據(jù)即可故痊,不管數(shù)據(jù)是否發(fā)送成功
Socket是一種不同計(jì)算機(jī)顶瞳,實(shí)時(shí)連接,比如說傳送文件,即時(shí)通訊
8.音視頻相關(guān)類
總體來說慨菱,分為幾個(gè)類
視頻錄制方面焰络,Camear攝像頭錄制視頻類,MediaProjection屏幕錄制視頻類
編碼方面抡柿,MediaCodec,MediaRecorder
預(yù)覽方面等恐,SurfaceView,GLSurfaceView,TextureView,VideoView
9.進(jìn)程和線程的區(qū)別
概念:進(jìn)程包括多個(gè)線程洲劣,一個(gè)程序一個(gè)進(jìn)程,多線程的優(yōu)點(diǎn)可以提高執(zhí)行效率课蔬,提高資源利用率
創(chuàng)建:Thread類和Runnable接口囱稽,
常用方法有:
start()用于啟動(dòng)線程
run()調(diào)用線程對(duì)象中的run方法
join()合并插隊(duì)到當(dāng)前線程
sellp()睡眠釋放cpu資源
setPriority()設(shè)置線程優(yōu)先級(jí)
10.內(nèi)存泄露如何查看和解決
概念:有些對(duì)象只有有限的生命周期,當(dāng)他們的任務(wù)完成之后二跋,它們將被垃圾回收战惊,如果在對(duì)象的生命周期本該結(jié)束的時(shí)候,這個(gè)對(duì)象還被一系列的引用扎即,著就會(huì)導(dǎo)致內(nèi)存泄露吞获。
解決方法:使用開源框架LeakCanary檢測(cè)針對(duì)性解決
常見的內(nèi)存泄露有:
單例造成的內(nèi)存泄露,例如單例中的Context生命周期大于本身Context生命周期
線程使用Hander造成的內(nèi)存卸扣谚鄙,當(dāng)activity已經(jīng)結(jié)束各拷,線程依然在運(yùn)行更新UI
非靜態(tài)類使用靜態(tài)變量導(dǎo)致無法回收釋放造成泄露
WebView網(wǎng)頁(yè)過多造成內(nèi)存泄露
資源未關(guān)閉造成泄露,例如數(shù)據(jù)庫(kù)使用完之后關(guān)閉連接
11.View的分發(fā)機(jī)制闷营,滑動(dòng)沖突
View的事件傳遞順序有3個(gè)重要的方法烤黍,dispatchTouchEvent()是否消耗了本次事件,onInterceptTouchEvent()是否攔截了本次事件傻盟,onTouchEvent()是否處理本次事件速蕊,滑動(dòng)沖突分為同方向滑動(dòng)沖突,例如ScrollView和ListView娘赴,同方向滑動(dòng)沖突规哲,可以計(jì)算ListView高度而動(dòng)態(tài)設(shè)置ListView的高度,ScrollView高度可變诽表。例如ViewPager和ListView,不同方向滑動(dòng)沖突媳叨,一個(gè)是橫向滑動(dòng)一個(gè)是豎直滑動(dòng),不同方向滑動(dòng)可以判斷滑動(dòng)的x关顷,y軸是橫向還是豎直滑動(dòng)糊秆,如果判斷得到是橫向滑動(dòng),就攔截ListView的事件议双,豎則反之痘番。
12.RecyclerView和ListView的區(qū)別
緩存上:前者緩存的是View+ViewHolder+flag,不用每次調(diào)用findViewById,后者則只是緩存View
刷新數(shù)據(jù)方面,前者提供了局部刷新汞舱,后者則全部刷新
13.recyclerView嵌套卡頓解決如何解決
設(shè)置預(yù)加載的數(shù)量LinearLayoutManager.setInitialPrefetchItemCount(4)伍纫,默認(rèn)是預(yù)加載2個(gè),
設(shè)置子項(xiàng)緩存昂芜,
設(shè)置自帶滑動(dòng)沖突解決屬性rv.setHasFixedSize(true); rv.setNestedScrollingEnabled(false);
可以完美解決莹规,不過Google不推薦RecyClerView嵌套使用,需要嵌套盡量找類似于ExpandableListView 第三方控件來解決
14,談MVC 泌神,MVP良漱,MVVM
MVC:View是可以直接訪問Model的!從而欢际,View里會(huì)包含Model信息母市,不可避免的還要包括一些 業(yè)務(wù)邏輯。 在MVC模型里损趋,更關(guān)注的Model的不變患久,而同時(shí)有多個(gè)對(duì)Model的不同顯示,及View浑槽。所以蒋失,在MVC模型里,Model不依賴于View桐玻,但是 View是依賴于Model的高镐。不僅如此,因?yàn)橛幸恍I(yè)務(wù)邏輯在View里實(shí)現(xiàn)了畸冲,導(dǎo)致要更改View也是比較困難的嫉髓,至少那些業(yè)務(wù)邏輯是無法重用的。
MVP:MVP 是從經(jīng)典的模式MVC演變而來邑闲,它們的基本思想有相通的地方:Controller/Presenter負(fù)責(zé)邏輯的處理算行,Model提供數(shù)據(jù),View負(fù) 責(zé)顯示苫耸。作為一種新的模式州邢,MVP與MVC有著一個(gè)重大的區(qū)別:在MVP中View并不直接使用Model,它們之間的通信是通過Presenter (MVC中的Controller)來進(jìn)行的褪子,所有的交互都發(fā)生在Presenter內(nèi)部量淌,而在MVC中View會(huì)從直接Model中讀取數(shù)據(jù)而不是通過 Controller。
MVVM:數(shù)據(jù)雙向綁定嫌褪,通過數(shù)據(jù)驅(qū)動(dòng)UI呀枢,M提供數(shù)據(jù),V視圖笼痛,VM即數(shù)據(jù)驅(qū)動(dòng)層
15.dagger2
Dagger2是一個(gè)主要用于依賴注入的框架裙秋,減少初始化對(duì)象操作琅拌,降低耦合度
16Android性能優(yōu)化
布局優(yōu)化: 減少布局層級(jí),使用ViewStub提高顯示速度摘刑,布局服用进宝,盡可能少使用warp_content,刪除空間中無用的屬性,避免過度繪制移除window默認(rèn)背景枷恕,按需顯示展位圖党晋,自定義View優(yōu)化,使用canvas.clipRect()識(shí)別可見區(qū)域
啟動(dòng)速度:采用分布加載徐块,異步加載未玻,延期加載提高應(yīng)用初始化速度,采用線程初始化數(shù)據(jù)等蛹锰,合理的刷新機(jī)制
內(nèi)存方面:防止內(nèi)存泄露,使用一些第三方工具檢測(cè)解決
代碼優(yōu)化:遵循Java生命周期
安裝包優(yōu)化:刪除無用資源深胳,優(yōu)化圖片绰疤,代碼混淆铜犬,避免重復(fù)庫(kù)存在,插件化
17.Hander原理
Handler轻庆,loop輪詢檢測(cè)發(fā)送消息到MessagerQuery,MessageQuery對(duì)Message入列癣猾,Handler回調(diào)方法處理消息,重寫handMessage方法刷新ui
18.SharedPreference跨進(jìn)程使用會(huì)怎么樣余爆?如何保證跨進(jìn)程使用安全纷宇?
在兩個(gè)應(yīng)用的manifest配置中好相同的shartdUserId屬性,A應(yīng)用正常保存數(shù)據(jù)蛾方,B應(yīng)用
createPackageContext("com.netease.nim.demo", CONTEXT_IGNORE_SECURITY)
獲取context然后獲取應(yīng)用數(shù)據(jù)像捶,為保證數(shù)據(jù)安全,使用加密存儲(chǔ)
19.推送到達(dá)率如何提高
判手機(jī)系統(tǒng)桩砰,小米使用小米推送拓春,華為使用華為推送,其他手機(jī)使用友盟推送
20.activity亚隅,fragment傳值問題
通過Bundle傳值硼莽,在activty定義變量傳值,擴(kuò)展fragment創(chuàng)建傳值
21.activity與fragment區(qū)別
生命周期:
fragment從創(chuàng)建倒銷毀整個(gè)生命周期依次為onAttach()→onCreate()→onCreateView()→onActivityCreated()→onStart()→onResume()→onPause()→onStop()→onDestroyView()→onDestroy()→onDetach()
與activity不同的方法有
onAttach():當(dāng)Fragment和Activity建立關(guān)聯(lián)的時(shí)候調(diào)用煮纵;
onCreateView():當(dāng)Fragment創(chuàng)建視圖調(diào)用懂鸵;
onActivityCreated:與Fragment相關(guān)聯(lián)的Activity完成onCreate()之后調(diào)用;
onDestoryView():在Fragment中的布局被移除時(shí)調(diào)用行疏;
onDetach():當(dāng)Fragment和Activity解除關(guān)聯(lián)時(shí)調(diào)用匆光;
activity常用的生命周期只有以下幾個(gè);
onCreate(): 表示 Activity 正在被創(chuàng)建酿联,常用來 初始化工作殴穴,比如調(diào)用 setContentView 加載界面布局資源,初始化 Activity 所需數(shù)據(jù)等;
onRestart():表示 Activity 正在重新啟動(dòng)采幌,一般情況下劲够,當(dāng)前Acitivty 從不可見重新變?yōu)榭梢姇r(shí),OnRestart就會(huì)被調(diào)用休傍;
onStart(): 表示 Activity 正在被啟動(dòng)征绎,此時(shí) Activity 可見但不在前臺(tái),還處于后臺(tái)磨取,無法與用戶交互人柿;
onResume(): 表示 Activity 獲得焦點(diǎn),此時(shí) Activity 可見且在前臺(tái)并開始活動(dòng)忙厌,這是與 onStart 的區(qū)別所在凫岖;
onPause(): 表示 Activity 正在停止,此時(shí)可做一些 存儲(chǔ)數(shù)據(jù)逢净、停止動(dòng)畫等工作哥放,但是不能太耗時(shí),因?yàn)檫@會(huì)影響到新 Activity的顯示爹土,onPause 必須先執(zhí)行完甥雕,新 Activity 的 onResume 才會(huì)執(zhí)行;
onStop(): 表示 Activity 即將停止胀茵,可以做一些稍微重量級(jí)的回收工作社露,比如注銷廣播接收器、關(guān)閉網(wǎng)絡(luò)連接等琼娘,同樣不能太耗時(shí)峭弟;
onDestroy(): 表示 Activity 即將被銷毀,這是 Activity 生命周期中的最后一個(gè)回調(diào)脱拼,常做 回收工作瞒瘸、資源釋放;
區(qū)別:
Fragment比Activity多出四個(gè)回調(diào)周期挪拟,控制操作上更靈活挨务;
Fragment可以在xml文件中直接寫入,也可以在Activity中動(dòng)態(tài)添加玉组;
Fragment可以使用show()/hide()或者replace()對(duì)Fragment進(jìn)行切換谎柄,切換的時(shí)候不會(huì)出現(xiàn)明顯的效果,Activity切換的時(shí)候會(huì)有明顯的翻頁(yè)或其他效果惯雳;
22.Fragment中add與replace的區(qū)別朝巫?
add不會(huì)重新初始化fragment,replace每次都會(huì);
添加相同的fragment時(shí)石景,replace不會(huì)有任何變化劈猿,add會(huì)報(bào)IllegalStateException 異常拙吉;
replace 先 remove 掉相同 id 的所有 fragment,然后在add 當(dāng)前的這個(gè) fragment揪荣,而 add 是覆蓋前一個(gè)fragment筷黔。所以如果使用 add 一般會(huì)伴隨 hide()和show(),避免布局重疊仗颈;
使用 add佛舱,如果應(yīng)用放在后臺(tái),或以其他方式被系統(tǒng)銷毀挨决,再打開時(shí)请祖,hide()中引用的 fragment 會(huì)銷毀,所以依然會(huì)出現(xiàn)布局重疊 bug脖祈,可以使用 replace 或使用 add時(shí)肆捕,添加一個(gè) tag 參數(shù);
23.FragmentPagerAdapter 與 與 FragmentStatePagerAdapter 的區(qū)別與使用場(chǎng)景盖高?
FragmentPagerAdapter 的每個(gè) Fragment 會(huì)持久的保存在 FragmentManager 中慎陵,只要用戶可以返回到頁(yè)面中,它都不會(huì)被銷毀或舞。因此適用于那些數(shù)據(jù) 相對(duì)靜態(tài)的頁(yè)荆姆,F(xiàn)ragment 數(shù)量也比較少的那種;FragmentStatePagerAdapter 只保留當(dāng)前頁(yè)面蒙幻,當(dāng)頁(yè)面不可見時(shí)映凳,該 Fragment 就會(huì)被消除,釋放其資源邮破。因此適用于那些 數(shù)據(jù)動(dòng)態(tài)性較大诈豌、 占用內(nèi)存較多,多 Fragment 的情況抒和;
24.說下Activity 的四種啟動(dòng)模式矫渔、應(yīng)用場(chǎng)景 ?
standard 標(biāo)準(zhǔn)模式: 每次啟動(dòng)一個(gè) Activity 都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例摧莽,不管這個(gè)實(shí)例是否已經(jīng)存在庙洼,此模式的 Activity 默認(rèn)會(huì)進(jìn)入啟動(dòng)它的 Activity 所屬的任務(wù)棧中;
singleTop 棧頂復(fù)用模式: 如果新 Activity 已經(jīng)位于任務(wù)棧的棧頂镊辕,那么此 Activity 不會(huì)被重新創(chuàng)建油够,同時(shí)會(huì)回調(diào) onNewIntent方法,如果新 Activity 實(shí)例已經(jīng)存在但不在棧頂征懈,那么Activity 依然會(huì)被重新創(chuàng)建石咬;
singleTask 棧內(nèi)復(fù)用模式: 只要 Activity 在一個(gè)任務(wù)棧中存在,那么多次啟動(dòng)此 Activity 都不會(huì)重新創(chuàng)建實(shí)例卖哎,并回調(diào)onNewIntent 方法鬼悠,此模式啟動(dòng) Activity A删性,系統(tǒng)首先會(huì)尋找是否存在 A 想要的任務(wù)棧,如果不存在焕窝,就會(huì)重新創(chuàng)建一個(gè)任務(wù)棧蹬挺,然后把創(chuàng)建好 A 的實(shí)例放到棧中;
singleInstance單實(shí)例模式: 這是一種加強(qiáng)的 singleTask 模式它掂,具有此種模式的 Activity 只能單獨(dú)地位于一個(gè)任務(wù)棧中汗侵,且此任務(wù)棧中只有唯一一個(gè)實(shí)例;
25.說下 Activity 跟 跟 window 群发, view 之間的關(guān)系晰韵?
Activity 創(chuàng)建時(shí)通過 attach()初始化了一個(gè) Window 也就是PhoneWindow,一個(gè) PhoneWindow 持有一個(gè)DecorView 的實(shí)例熟妓,DecorView 本身是一個(gè) FrameLayout雪猪,繼承于 View,Activty 通過setContentView 將xml 布局控件不斷 addView()添加到 View 中起愈,最終顯示到 Window 于我們交互只恨;
26.橫豎屏切換的Activity 生命周期變化?
不設(shè)置 Activity 的 android:configChanges 時(shí)抬虽,切屏?xí)N毀當(dāng)前Activity官觅,然后重新加載調(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次阐污,切豎屏?xí)r會(huì)執(zhí)行兩次休涤;onPause()→onStop()→onDestory()→onCreate()→onStart()→onResume()
設(shè)置 Activity 的 android:configChanges=" orientation",經(jīng)過機(jī)型測(cè)試
在 Android5.1 即 即 API 3 23 級(jí)別下笛辟,切屏還是會(huì)重新調(diào)用各個(gè)生命周期功氨,切橫、豎屏?xí)r只會(huì)執(zhí)行一次
在 Android9 即 即 API 8 28 級(jí)別下手幢,切屏不會(huì)重新調(diào)用各個(gè)生命周期捷凄,只會(huì)執(zhí)行 onConfigurationChanged方法
官方糾正后,原話如下
如果您的應(yīng)用面向 Android 2 3.2 即 即 API 級(jí)別 3 13 或更
高級(jí)別(按照 minSdkVersion 和 targetSdkVersion)
未完待續(xù)......