筆者由于在找工作,所以近期最主要的任務(wù)就是準(zhǔn)備面試,不打無(wú)準(zhǔn)備之仗。只有你準(zhǔn)備充分了,那么你想要的機(jī)會(huì)才有機(jī)會(huì)入你懷中。
筆者會(huì)將準(zhǔn)備面試的學(xué)習(xí)過(guò)程記錄下來(lái),方便自己復(fù)盤的同時(shí)也希望能給一道找工作的小伙伴們一些幫助。筆者準(zhǔn)備的內(nèi)容大綱如下

接下來(lái)開始本篇博客的正菜
1.AsyncTask的缺陷?使用時(shí)有什么需要注意的點(diǎn)?
(1)通過(guò)AsyncTask可以更加方便的執(zhí)行后臺(tái)任務(wù)以及在主線程中訪問(wèn)ui,但是并不合適執(zhí)行特別耗時(shí)的后臺(tái)任務(wù)。
這個(gè)主要是因?yàn)樵贏ndroid 3.0之后它的內(nèi)部是串行執(zhí)行任務(wù)的。串行執(zhí)行任務(wù)效率就會(huì)比較低,雖然可以通過(guò)調(diào)用AsyncTask的executeOnExecutor方法并行執(zhí)行任務(wù),但是在并發(fā)程度比較高的情況下,很容易帶來(lái)并發(fā)錯(cuò)誤,這也是Android 3.0之后將并行改成串行的主要原因。
(2)注意AsyncTask的內(nèi)存泄露、生命周期問(wèn)題
- 內(nèi)存泄漏
如果AsyncTask被聲明為Activity的非靜態(tài)的內(nèi)部類,那么AsyncTask會(huì)保留一個(gè)對(duì)Activity的引用。如果Activity已經(jīng)被銷毀,AsyncTask的后臺(tái)線程還在執(zhí)行,它將續(xù)在內(nèi)存里保留這個(gè)引用,導(dǎo)致Activity無(wú)法被內(nèi)存回收,引起內(nèi)存泄漏。
解決方法:
(1)將AsyncTask改為靜態(tài)內(nèi)部類,也可以在內(nèi)部類AsyncTask里面持有Activity的弱引用。
(2)在Activity的onDestroy生命周期方法里調(diào)用AsyncTask的cancel銷毀AsyncTask
- 生命周期
在Activity中創(chuàng)建的AsyncTask會(huì)一直執(zhí)行,直到doInBackground()方法執(zhí)行完畢,所以我們?cè)阡N毀Activity的時(shí)候也需要銷毀AsyncTask。通過(guò)在Activity的onDestroy生命周期方法里調(diào)用AsyncTask的cancel銷毀AsyncTask
建議配合Android開發(fā)藝術(shù)探索(P392) 同時(shí)食用
2.談?wù)凙ndroid的消息機(jī)制?
Android的消息機(jī)制主要指Handler的運(yùn)行機(jī)制以及Handler所附帶的MessageQueue和Looper的工作過(guò)程,這三者實(shí)際上是一個(gè)整體。Handler的主要作用是將一個(gè)任務(wù)切換到某個(gè)指定的線程中去執(zhí)行。
那Handler是怎么工作的呢?
Handler主要包含消息的發(fā)送和接收。某線程借助Handler發(fā)送一條消息,就會(huì)插入到MessageQueue這個(gè)消息隊(duì)列中,Looper不斷的輪詢這個(gè)消息隊(duì)列,如果輪詢到新的消息到來(lái)就會(huì)去取出并處理它,再交由Handler的dispatchMessage方法處理消息,dispatchMessage方法是在Handler所在的線程,所以于此同時(shí),線程也就切換到了Handler所在的線程了。
MessageQueue的內(nèi)部實(shí)現(xiàn)是一個(gè)隊(duì)列嗎?
不是,它用一個(gè)單鏈表來(lái)維護(hù)消息列表,因?yàn)镸essageQueue需要不斷的插入和刪除數(shù)據(jù),而單鏈表實(shí)現(xiàn)插入和刪除的效率高。
建議配合該博客同時(shí)食用 聊聊Android的消息機(jī)制
3.Thread、AsyncTask、IntentService的使用場(chǎng)景與特點(diǎn)?
- Thread是一個(gè)普通的線程,獨(dú)立于Activity的。當(dāng)Activity 被 finish 后,如果沒有主動(dòng)停止 Thread或者 run 方法沒有執(zhí)行完,就會(huì)一直執(zhí)行下去。
- AsyncTask是 封裝了兩個(gè)線程池和一個(gè)Handler,(SerialExecutor用于排隊(duì),THREAD_POOL_EXECUTOR為真正的執(zhí)行任務(wù),Handler用于將工作線程切換到主線程)。它適合網(wǎng)絡(luò)請(qǐng)求或者簡(jiǎn)單數(shù)據(jù)處理。但不適合處理特別耗時(shí)的后臺(tái)任務(wù)。
- IntentService本質(zhì)上是封裝了HandlerThread和Handler的異步框架。當(dāng)任務(wù)會(huì)執(zhí)行完成后,它會(huì)自動(dòng)停止,因?yàn)樗且粋€(gè)服務(wù),所以它的優(yōu)先級(jí)比線程高很多,不容易被殺死,所以適合執(zhí)行一些高優(yōu)先級(jí)的耗時(shí)的后臺(tái)任務(wù)。
HandlerThread就是可以使用Handler的Thread,它是一個(gè)串行隊(duì)列,有自己的內(nèi)部Looper對(duì)象,背后只有一個(gè)線程。
4.Serializable和Parcelable的比較
它們都是用于對(duì)象序列化的接口,有的時(shí)候我們需要把對(duì)象持久化到存儲(chǔ)設(shè)備或者通過(guò)網(wǎng)絡(luò)進(jìn)行傳輸給其他客戶端,這個(gè)時(shí)候就需要完成對(duì)象的持久化。通過(guò)這兩個(gè)接口我們可以序列化來(lái)完成對(duì)象的持久化。
- Serializable(Java自帶)
Serializable是序列化的意思,表示將一個(gè)對(duì)象轉(zhuǎn)換成存儲(chǔ)或可傳輸?shù)臓顟B(tài)。序列化后的對(duì)象可以在網(wǎng)絡(luò)上進(jìn)傳輸,也可以存儲(chǔ)到本地。
- Parcelable(android專用)
使用Parcelable也可以實(shí)現(xiàn)對(duì)象序列化果,不過(guò)不同于Serializable,Parcelable方式的實(shí)現(xiàn)原理是將一個(gè)完整的對(duì)象進(jìn)行分解,而分解后的每一部分都是Intent所支持的數(shù)據(jù)類型,這也就實(shí)現(xiàn)傳遞對(duì)象的功能。
總結(jié)
Serializable需要大量的I/O操作,雖然使用時(shí)操作方便但是開銷很大。Parcelable使用起來(lái)稍微麻煩點(diǎn),但它的效率高,它是Android推薦的序列化方式,首選Parcelable。
建議配合Android開發(fā)藝術(shù)探索(P47) 同時(shí)食用
5.Android中有哪幾種解析xml的方式,官方推薦哪種?它們的原理和區(qū)別?
有DOM、SAX、PULL三種解析方式
- DOM是基于文檔驅(qū)動(dòng)的方式??捎糜谥苯釉L問(wèn) XML 文檔的各個(gè)部分。
它是一次性全部將內(nèi)容加載在內(nèi)存中,生成一個(gè)樹狀結(jié)構(gòu),它沒有涉及回調(diào)和復(fù)雜的狀態(tài)管理。缺點(diǎn)是加載大文檔時(shí)效率低下。 - SAX使用流式處理的方式。是以事件為驅(qū)動(dòng)的XML API,使用回調(diào)函數(shù)來(lái)實(shí)現(xiàn)。優(yōu)點(diǎn)是解析速度快,占用內(nèi)存少。缺點(diǎn)是不能倒退。
- PULL內(nèi)置于 Android 系統(tǒng)中。也是官方解析布局文件所使用的方式。
Pull 與 SAX 有點(diǎn)類似,都提供了類似的事件,如開始元素和結(jié)束元素。不同的是Pull解析器并沒有強(qiáng)制要求提供觸發(fā)的方法。因?yàn)樗|發(fā)的事件不是一個(gè)方法,而是一個(gè)數(shù)字。它使用方便,效率高。
建議配合該博客同時(shí)食用 Android中解析XML格式數(shù)據(jù)的方法