最近,在BOSS直聘網(wǎng)站上面投了自己的簡(jiǎn)歷,今天晚上突然那邊來(lái)了面試電話(huà),直接就是一輪虐。
首先簡(jiǎn)單的做了一下自我介紹,其實(shí)這里面也有講究的,當(dāng)時(shí)沒(méi)注意到。面試官對(duì)你進(jìn)行面試,肯定是看了一下自己的簡(jiǎn)歷的。這時(shí)候自我介紹就最好不要說(shuō)一些簡(jiǎn)歷上面沒(méi)提到的東西。因?yàn)樽约菏窃贖W公司搞Android 機(jī)頂盒應(yīng)用層開(kāi)發(fā)的,也沒(méi)有接觸到一些新技術(shù)框架,平時(shí)都是自己自學(xué),看看博客,參照網(wǎng)上的一些大神的文章,簡(jiǎn)單的學(xué)習(xí)了解Volley、ButterKnife、OKHttp、Retofit、EventBus。
接下來(lái)就問(wèn)一下Android 消息機(jī)制,面試官有提示到Handler、Looper、MessageQueue、Message。
其實(shí)Android中每一個(gè)Thread都跟著一個(gè)Looper,Looper可以幫助Thread維護(hù)一個(gè)消息隊(duì)列,但是Looper和Handler沒(méi)有什么關(guān)系,每一個(gè)Looper對(duì)象由包含一個(gè)MessageQueue,MessageQueue里面又飽含著Message對(duì)象,Message對(duì)象會(huì)持有一個(gè)Handler對(duì)象的引用。當(dāng)我們?cè)谧泳€(xiàn)程里面新建Handler對(duì)象的時(shí)候,必須要調(diào)用Looper. prepare()方法來(lái)創(chuàng)建與該Handler線(xiàn)程所對(duì)應(yīng)的Looper對(duì)象了(其底層是使用ThreadLocal也就是線(xiàn)程局部變量來(lái)存儲(chǔ)Looper對(duì)象)。當(dāng)然了在主線(xiàn)程里面創(chuàng)建Handler就不需要調(diào)用了,應(yīng)為Activity啟動(dòng)的時(shí)候就已經(jīng)在main方法里面調(diào)用了。當(dāng)我們調(diào)用Handler的sendMessage(Message)發(fā)送消息的時(shí)候,其實(shí)是通過(guò)Looper對(duì)象里面的MessageQueue的enqueueMessage(Message)添加到了其阻塞隊(duì)列里面去了。然后Looper.loop()方法會(huì)從阻塞隊(duì)列里面取出Message對(duì)象,回調(diào)Handler的handleMessage方法。
延遲time時(shí)間發(fā)送消息:mHandler.postDelayed(runnable,time)
取消發(fā)送:mHandler.removeCallbacks(runnable)
參考博客:
1. 自定義Handler
2. Android異步消息機(jī)制
第二個(gè)問(wèn)題是,事件分發(fā)機(jī)制
這個(gè)問(wèn)題很尷尬,當(dāng)時(shí)由于很緊張,竟然忘記了dispatchTouchEvent() 事件分發(fā)函數(shù)名叫啥?;卮鸬牟皇呛芎?,這個(gè)需要反思一下。
什么是事件?當(dāng)我們點(diǎn)擊屏幕的時(shí)候會(huì)產(chǎn)生一個(gè)Touch事件,這個(gè)事件被封裝為一個(gè)名叫MotionEvent對(duì)象,有MotionEvent.ACTION_DOWN、MotionEvent.ACTION_MOVE、MotionEvent.ACTION_CANCLE(非人為操作)、MotionEvent.ACTION_UP。事件分發(fā)的本質(zhì)其實(shí)就是將事件分發(fā)到具體的View處理的過(guò)程。首先事件會(huì)從Activity傳到ViewGroup再到View。
dispatchTouchEvent() 事件分發(fā)函數(shù)
onInterceptTouchEvent(),只存在于ViewGroup類(lèi)中,事件攔截函數(shù)
onTouchEvent() 事件處理函數(shù)
參考博客
1. View一問(wèn)一答*事件分發(fā)機(jī)制
第三個(gè)問(wèn)題就是Activity的啟動(dòng)模式
其實(shí)這個(gè)問(wèn)題可以擴(kuò)展出很多關(guān)于Activity的生命周期、切換屏幕、異常退出、數(shù)據(jù)保存、進(jìn)程的優(yōu)先級(jí)等等??梢詤⒖疾┛?a href="http://www.itdecent.cn/p/9aba0677c562" target="_blank">BAT大牛面試之談解密Android
- standard 這是默認(rèn)模式,每次激活A(yù)ctivity時(shí)都會(huì)創(chuàng)建Activity實(shí)例,并放入任務(wù)棧中。使用場(chǎng)景:大多數(shù)Activity。
- singleTop 如果在任務(wù)的棧頂正好存在該Activity的實(shí)例,就重用該實(shí)例( 會(huì)調(diào)用實(shí)例的 onNewIntent() ),否則就會(huì)創(chuàng)建新的實(shí)例并放入棧頂,即使棧中已經(jīng)存在該Activity的實(shí)例,只要不在棧頂,都會(huì)創(chuàng)建新的實(shí)例。使用場(chǎng)景如新聞?lì)惢蛘唛喿x類(lèi)App的內(nèi)容頁(yè)面。
- singleTask 如果在棧中已經(jīng)有該Activity的實(shí)例,就重用該實(shí)例(會(huì)調(diào)用實(shí)例的 onNewIntent() )。重用時(shí),會(huì)讓該實(shí)例回到棧頂,因此在它上面的實(shí)例將會(huì)被移出棧。如果棧中不存在該實(shí)例,將會(huì)創(chuàng)建新的實(shí)例放入棧中。使用場(chǎng)景如瀏覽器的主界面。不管從多少個(gè)應(yīng)用啟動(dòng)瀏覽器,只會(huì)啟動(dòng)主界面一次,其余情況都會(huì)走onNewIntent,并且會(huì)清空主界面上面的其他頁(yè)面。
- singleInstance 在一個(gè)新棧中創(chuàng)建該Activity的實(shí)例,并讓多個(gè)應(yīng)用共享該棧中的該Activity實(shí)例。一旦該模式的Activity實(shí)例已經(jīng)存在于某個(gè)棧中,任何應(yīng)用再激活該Activity時(shí)都會(huì)重用該棧中的實(shí)例( 會(huì)調(diào)用實(shí)例的 onNewIntent() )。其效果相當(dāng)于多個(gè)應(yīng)用共享一個(gè)應(yīng)用,不管誰(shuí)激活該 Activity 都會(huì)進(jìn)入同一個(gè)應(yīng)用中。使用場(chǎng)景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設(shè)置分離。singleInstance不要用于中間頁(yè)面,如果用于中間頁(yè)面,跳轉(zhuǎn)會(huì)有問(wèn)題,比如:A -> B (singleInstance) -> C,完全退出后,在此啟動(dòng),首先打開(kāi)的是B。
第四個(gè)問(wèn)題是說(shuō)了一下平時(shí)都關(guān)注了哪些開(kāi)源框架,對(duì)其了解程度。
- Volley 異步網(wǎng)絡(luò)請(qǐng)求框架,適合數(shù)據(jù)量較小,但訪(fǎng)問(wèn)頻繁的操作。其內(nèi)部會(huì)有一個(gè)緩存線(xiàn)程CacheDispatcher、4個(gè)網(wǎng)絡(luò)請(qǐng)求線(xiàn)程N(yùn)etWorkDispatcher。
參考博客
Android異步網(wǎng)絡(luò)請(qǐng)求框架-Volley
- ButterKnife 依賴(lài)注入框架,采用的是編譯器時(shí)期注入方式,得到注解的字段屬性與所在類(lèi) , 進(jìn)而生成注入文件,生成一個(gè)注入類(lèi)的內(nèi)部類(lèi),再進(jìn)行字段處理 , 編譯之后就會(huì)合并到注入類(lèi)中,達(dá)到植入新代碼段的目的。
當(dāng)然還有一些像OKHttp網(wǎng)絡(luò)請(qǐng)求框架、Retorfit2、RxJava 響應(yīng)式編程、EventBus事件總線(xiàn)。這些東西后面再打算進(jìn)行詳細(xì)分析。