国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

2019 Android 高級(jí)面試題總結(jié)

wums / 2453人閱讀

摘要:子線程往消息隊(duì)列發(fā)送消息,并且往管道文件寫(xiě)數(shù)據(jù),主線程即被喚醒,從管道文件讀取數(shù)據(jù),主線程被喚醒只是為了讀取消息,當(dāng)消息讀取完畢,再次睡眠。因此的循環(huán)并不會(huì)對(duì)性能有過(guò)多的消耗。

說(shuō)下你所知道的設(shè)計(jì)模式與使用場(chǎng)景
a.建造者模式:

將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。

使用場(chǎng)景比如最常見(jiàn)的AlertDialog,拿我們開(kāi)發(fā)過(guò)程中舉例,比如Camera開(kāi)發(fā)過(guò)程中,可能需要設(shè)置一個(gè)初始化的相機(jī)配置,設(shè)置攝像頭方向,閃光燈開(kāi)閉,成像質(zhì)量等等,這種場(chǎng)景下就可以使用建造者模式

裝飾者模式:動(dòng)態(tài)的給一個(gè)對(duì)象添加一些額外的職責(zé),就增加功能來(lái)說(shuō),裝飾模式比生成子類(lèi)更為靈活。裝飾者模式可以在不改變?cè)蓄?lèi)結(jié)構(gòu)的情況下曾強(qiáng)類(lèi)的功能,比如Java中的BufferedInputStream 包裝FileInputStream,舉個(gè)開(kāi)發(fā)中的例子,比如在我們現(xiàn)有網(wǎng)絡(luò)框架上需要增加新的功能,那么再包裝一層即可,裝飾者模式解決了繼承存在的一些問(wèn)題,比如多層繼承代碼的臃腫,使代碼邏輯更清晰

觀察者模式:
代理模式:
門(mén)面模式:
單例模式:
生產(chǎn)者消費(fèi)者模式:

java語(yǔ)言的特點(diǎn)與OOP思想

這個(gè)通過(guò)對(duì)比來(lái)描述,比如面向?qū)ο蠛兔嫦蜻^(guò)程的對(duì)比,針對(duì)這兩種思想的對(duì)比,還可以舉個(gè)開(kāi)發(fā)中的例子,比如播放器的實(shí)現(xiàn),面向過(guò)程的實(shí)現(xiàn)方式就是將播放視頻的這個(gè)功能分解成多個(gè)過(guò)程,比如,加載視頻地址,獲取視頻信息,初始化解碼器,選擇合適的解碼器進(jìn)行解碼,讀取解碼后的幀進(jìn)行視頻格式轉(zhuǎn)換和音頻重采樣,然后讀取幀進(jìn)行播放,這是一個(gè)完整的過(guò)程,這個(gè)過(guò)程中不涉及類(lèi)的概念,而面向?qū)ο笞畲蟮奶攸c(diǎn)就是類(lèi),封裝繼承和多態(tài)是核心,同樣的以播放器為例,一面向?qū)ο蟮姆绞絹?lái)實(shí)現(xiàn),將會(huì)針對(duì)每一個(gè)功能封裝出一個(gè)對(duì)象,吧如說(shuō)Muxer,獲取視頻信息,Decoder,解碼,格式轉(zhuǎn)換器,視頻播放器,音頻播放器等,每一個(gè)功能對(duì)應(yīng)一個(gè)對(duì)象,由這個(gè)對(duì)象來(lái)完成對(duì)應(yīng)的功能,并且遵循單一職責(zé)原則,一個(gè)對(duì)象只做它相關(guān)的事情

說(shuō)下java中的線程創(chuàng)建方式,線程池的工作原理。

java中有三種創(chuàng)建線程的方式,或者說(shuō)四種

1.繼承Thread類(lèi)實(shí)現(xiàn)多線程
2.實(shí)現(xiàn)Runnable接口
3.實(shí)現(xiàn)Callable接口
4.通過(guò)線程池

線程池的工作原理:線程池可以減少創(chuàng)建和銷(xiāo)毀線程的次數(shù),從而減少系統(tǒng)資源的消耗,當(dāng)一個(gè)任務(wù)提交到線程池時(shí)

a. 首先判斷核心線程池中的線程是否已經(jīng)滿(mǎn)了,如果沒(méi)滿(mǎn),則創(chuàng)建一個(gè)核心線程執(zhí)行任務(wù),否則進(jìn)入下一步

b. 判斷工作隊(duì)列是否已滿(mǎn),沒(méi)有滿(mǎn)則加入工作隊(duì)列,否則執(zhí)行下一步

c. 判斷線程數(shù)是否達(dá)到了最大值,如果不是,則創(chuàng)建非核心線程執(zhí)行
任務(wù),否則執(zhí)行飽和策略,默認(rèn)拋出異常

說(shuō)下 handler 原理

Handler,Message,looper 和 MessageQueue 構(gòu)成了安卓的消息機(jī)制,handler創(chuàng)建后可以通過(guò) sendMessage 將消息加入消息隊(duì)列,然后 looper不斷的將消息從 MessageQueue 中取出來(lái),回調(diào)到 Hander 的 handleMessage方法,從而實(shí)現(xiàn)線程的通信。

從兩種情況來(lái)說(shuō),第一在UI線程創(chuàng)建Handler,此時(shí)我們不需要手動(dòng)開(kāi)啟looper,因?yàn)樵趹?yīng)用啟動(dòng)時(shí),在ActivityThread的main方法中就創(chuàng)建了一個(gè)當(dāng)前主線程的looper,并開(kāi)啟了消息隊(duì)列,消息隊(duì)列是一個(gè)無(wú)限循環(huán),為什么無(wú)限循環(huán)不會(huì)ANR?因?yàn)榭梢哉f(shuō),應(yīng)用的整個(gè)生命周期就是運(yùn)行在這個(gè)消息循環(huán)中的,安卓是由事件驅(qū)動(dòng)的,Looper.loop不斷的接收處理事件,每一個(gè)點(diǎn)擊觸摸或者Activity每一個(gè)生命周期都是在Looper.loop的控制之下的,looper.loop一旦結(jié)束,應(yīng)用程序的生命周期也就結(jié)束了。我們可以想想什么情況下會(huì)發(fā)生ANR,第一,事件沒(méi)有得到處理,第二,事件正在處理,但是沒(méi)有及時(shí)完成,而對(duì)事件進(jìn)行處理的就是looper,所以只能說(shuō)事件的處理如果阻塞會(huì)導(dǎo)致ANR,而不能說(shuō)looper的無(wú)限循環(huán)會(huì)ANR

另一種情況就是在子線程創(chuàng)建Handler,此時(shí)由于這個(gè)線程中沒(méi)有默認(rèn)開(kāi)啟的消息隊(duì)列,所以我們需要手動(dòng)調(diào)用looper.prepare(),并通過(guò)looper.loop開(kāi)啟消息

主線程Looper從消息隊(duì)列讀取消息,當(dāng)讀完所有消息時(shí),主線程阻塞。子線程往消息隊(duì)列發(fā)送消息,并且往管道文件寫(xiě)數(shù)據(jù),主線程即被喚醒,從管道文件讀取數(shù)據(jù),主線程被喚醒只是為了讀取消息,當(dāng)消息讀取完畢,再次睡眠。因此loop的循環(huán)并不會(huì)對(duì)CPU性能有過(guò)多的消耗。

內(nèi)存泄漏的場(chǎng)景和解決辦法

1.非靜態(tài)內(nèi)部類(lèi)的靜態(tài)實(shí)例

非靜態(tài)內(nèi)部類(lèi)會(huì)持有外部類(lèi)的引用,如果非靜態(tài)內(nèi)部類(lèi)的實(shí)例是靜態(tài)的,就會(huì)長(zhǎng)期的維持著外部類(lèi)的引用,組織被系統(tǒng)回收,解決辦法是使用靜態(tài)內(nèi)部類(lèi)

2.多線程相關(guān)的匿名內(nèi)部類(lèi)和非靜態(tài)內(nèi)部類(lèi)

匿名內(nèi)部類(lèi)同樣會(huì)持有外部類(lèi)的引用,如果在線程中執(zhí)行耗時(shí)操作就有可能發(fā)生內(nèi)存泄漏,導(dǎo)致外部類(lèi)無(wú)法被回收,直到耗時(shí)任務(wù)結(jié)束,解決辦法是在頁(yè)面退出時(shí)結(jié)束線程中的任務(wù)

3.Handler內(nèi)存泄漏

Handler導(dǎo)致的內(nèi)存泄漏也可以被歸納為非靜態(tài)內(nèi)部類(lèi)導(dǎo)致的,Handler內(nèi)部message是被存儲(chǔ)在MessageQueue中的,有些message不能馬上被處理,存在的時(shí)間會(huì)很長(zhǎng),導(dǎo)致handler無(wú)法被回收,如果handler是非靜態(tài)的,就會(huì)導(dǎo)致它的外部類(lèi)無(wú)法被回收,解決辦法是1.使用靜態(tài)handler,外部類(lèi)引用使用弱引用處理2.在退出頁(yè)面時(shí)移除消息隊(duì)列中的消息

4.Context導(dǎo)致內(nèi)存泄漏

根據(jù)場(chǎng)景確定使用Activity的Context還是Application的Context,因?yàn)槎呱芷诓煌瑢?duì)于不必須使用Activity的Context的場(chǎng)景(Dialog),一律采用Application的Context,單例模式是最常見(jiàn)的發(fā)生此泄漏的場(chǎng)景,比如傳入一個(gè)Activity的Context被靜態(tài)類(lèi)引用,導(dǎo)致無(wú)法回收

5.靜態(tài)View導(dǎo)致泄漏

使用靜態(tài)View可以避免每次啟動(dòng)Activity都去讀取并渲染View,但是靜態(tài)View會(huì)持有Activity的引用,導(dǎo)致無(wú)法回收,解決辦法是在Activity銷(xiāo)毀的時(shí)候?qū)㈧o態(tài)View設(shè)置為null(View一旦被加載到界面中將會(huì)持有一個(gè)Context對(duì)象的引用,在這個(gè)例子中,這個(gè)context對(duì)象是我們的Activity,聲明一個(gè)靜態(tài)變量引用這個(gè)View,也就引用了activity)

6.WebView導(dǎo)致的內(nèi)存泄漏

WebView只要使用一次,內(nèi)存就不會(huì)被釋放,所以WebView都存在內(nèi)存泄漏的問(wèn)題,通常的解決辦法是為WebView單開(kāi)一個(gè)進(jìn)程,使用AIDL進(jìn)行通信,根據(jù)業(yè)務(wù)需求在合適的時(shí)機(jī)釋放掉

7.資源對(duì)象未關(guān)閉導(dǎo)致

如Cursor,F(xiàn)ile等,內(nèi)部往往都使用了緩沖,會(huì)造成內(nèi)存泄漏,一定要確保關(guān)閉它并將引用置為null

8.集合中的對(duì)象未清理

集合用于保存對(duì)象,如果集合越來(lái)越大,不進(jìn)行合理的清理,尤其是入股集合是靜態(tài)的

9.Bitmap導(dǎo)致內(nèi)存泄漏

bitmap是比較占內(nèi)存的,所以一定要在不使用的時(shí)候及時(shí)進(jìn)行清理,避免靜態(tài)變量持有大的bitmap對(duì)象

10.監(jiān)聽(tīng)器未關(guān)閉

很多需要register和unregister的系統(tǒng)服務(wù)要在合適的時(shí)候進(jìn)行unregister,手動(dòng)添加的listener也需要及時(shí)移除

如何避免OOM?

1.使用更加輕量的數(shù)據(jù)結(jié)構(gòu):如使用ArrayMap/SparseArray替代HashMap,HashMap更耗內(nèi)存,因?yàn)樗枰~外的實(shí)例對(duì)象來(lái)記錄Mapping操作,SparseArray更加高效,因?yàn)樗苊饬薑ey Value的自動(dòng)裝箱,和裝箱后的解箱操作

2.便面枚舉的使用,可以用靜態(tài)常量或者注解@IntDef替代

3.Bitmap優(yōu)化:

a.尺寸壓縮:通過(guò)InSampleSize設(shè)置合適的縮放
b.顏色質(zhì)量:設(shè)置合適的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差異
c.inBitmap:使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經(jīng)存在的內(nèi)存區(qū)域,新解碼的Bitmap會(huì)嘗試去使用之前那張Bitmap在Heap中所占據(jù)的pixel data內(nèi)存區(qū)域,而不是去問(wèn)內(nèi)存重新申請(qǐng)一塊區(qū)域來(lái)存放Bitmap。利用這種特性,即使是上千張的圖片,也只會(huì)僅僅只需要占用屏幕所能夠顯示的圖片數(shù)量的內(nèi)存大小,但復(fù)用存在一些限制,具體體現(xiàn)在:在Android 4.4之前只能重用相同大小的Bitmap的內(nèi)存,而Android 4.4及以后版本則只要后來(lái)的Bitmap比之前的小即可。使用inBitmap參數(shù)前,每創(chuàng)建一個(gè)Bitmap對(duì)象都會(huì)分配一塊內(nèi)存供其使用,而使用了inBitmap參數(shù)后,多個(gè)Bitmap可以復(fù)用一塊內(nèi)存,這樣可以提高性能

4.StringBuilder替代String: 在有些時(shí)候,代碼中會(huì)需要使用到大量的字符串拼接的操作,這種時(shí)候有必要考慮使用StringBuilder來(lái)替代頻繁的“+”

5.避免在類(lèi)似onDraw這樣的方法中創(chuàng)建對(duì)象,因?yàn)樗鼤?huì)迅速占用大量?jī)?nèi)存,引起頻繁的GC甚至內(nèi)存抖動(dòng)

6.減少內(nèi)存泄漏也是一種避免OOM的方法

說(shuō)下 Activity 的啟動(dòng)模式,生命周期,兩個(gè) Activity 跳轉(zhuǎn)的生命周期,如果一個(gè) Activity 跳轉(zhuǎn)另一個(gè) Activity 再按下 Home 鍵在回到 Activity 的生命周期是什么樣的

啟動(dòng)模式

Standard 模式:Activity 可以有多個(gè)實(shí)例,每次啟動(dòng) Activity,無(wú)論任務(wù)棧中是否已經(jīng)有這個(gè)Activity的實(shí)例,系統(tǒng)都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例

SingleTop模式:當(dāng)一個(gè)singleTop模式的Activity已經(jīng)位于任務(wù)棧的棧頂,再去啟動(dòng)它時(shí),不會(huì)再創(chuàng)建新的實(shí)例,如果不位于棧頂,就會(huì)創(chuàng)建新的實(shí)例

SingleTask模式:如果Activity已經(jīng)位于棧頂,系統(tǒng)不會(huì)創(chuàng)建新的Activity實(shí)例,和singleTop模式一樣。但Activity已經(jīng)存在但不位于棧頂時(shí),系統(tǒng)就會(huì)把該Activity移到棧頂,并把它上面的activity出棧

SingleInstance模式:singleInstance 模式也是單例的,但和singleTask不同,singleTask 只是任務(wù)棧內(nèi)單例,系統(tǒng)里是可以有多個(gè)singleTask Activity實(shí)例的,而 singleInstance Activity 在整個(gè)系統(tǒng)里只有一個(gè)實(shí)例,啟動(dòng)一singleInstanceActivity 時(shí),系統(tǒng)會(huì)創(chuàng)建一個(gè)新的任務(wù)棧,并且這個(gè)任務(wù)棧只有他一個(gè)Activity

生命周期

onCreate onStart onResume onPause onStop onDestroy
兩個(gè) Activity 跳轉(zhuǎn)的生命周期

1.啟動(dòng)A
onCreate - onStart - onResume

2.在A中啟動(dòng)B
ActivityA onPause
ActivityB onCreate
ActivityB onStart
ActivityB onResume
ActivityA onStop

3.從B中返回A(按物理硬件返回鍵)
ActivityB onPause
ActivityA onRestart
ActivityA onStart
ActivityA onResume
ActivityB onStop
ActivityB onDestroy

4.繼續(xù)返回

ActivityA onPause
ActivityA onStop
ActivityA onDestroy

onRestart 的調(diào)用場(chǎng)景

(1)按下home鍵之后,然后切換回來(lái),會(huì)調(diào)用onRestart()。
(2)從本Activity跳轉(zhuǎn)到另一個(gè)Activity之后,按back鍵返回原來(lái)Activity,會(huì)調(diào)用onRestart();
(3)從本Activity切換到其他的應(yīng)用,然后再?gòu)钠渌麘?yīng)用切換回來(lái),會(huì)調(diào)用onRestart();

說(shuō)下 Activity 的橫豎屏的切換的生命周期,用那個(gè)方法來(lái)保存數(shù)據(jù),兩者的區(qū)別。觸發(fā)在什么時(shí)候在那個(gè)方法里可以獲取數(shù)據(jù)等。
是否了解SurfaceView,它是什么?他的繼承方式是什么?他與View的區(qū)別(從源碼角度,如加載,繪制等)。

SurfaceView中采用了雙緩沖機(jī)制,保證了UI界面的流暢性,同時(shí) SurfaceView 不在主線程中繪制,而是另開(kāi)辟一個(gè)線程去繪制,所以它不妨礙UI線程;

SurfaceView 繼承于View,他和View主要有以下三點(diǎn)區(qū)別:

(1)View底層沒(méi)有雙緩沖機(jī)制,SurfaceView有;

(2)view主要適用于主動(dòng)更新,而SurfaceView適用與被動(dòng)的更新,如頻繁的刷新

(3)view會(huì)在主線程中去更新UI,而SurfaceView則在子線程中刷新;

SurfaceView的內(nèi)容不在應(yīng)用窗口上,所以不能使用變換(平移、縮放、旋轉(zhuǎn)等)。也難以放在ListView或者ScrollView中,不能使用UI控件的一些特性比如View.setAlpha()

View:顯示視圖,內(nèi)置畫(huà)布,提供圖形繪制函數(shù)、觸屏事件、按鍵事件函數(shù)等;必須在UI主線程內(nèi)更新畫(huà)面,速度較慢。

SurfaceView:基于view視圖進(jìn)行拓展的視圖類(lèi),更適合2D游戲的開(kāi)發(fā);是view的子類(lèi),類(lèi)似使用雙緩機(jī)制,在新的線程中更新畫(huà)面所以刷新界面速度比view快,Camera預(yù)覽界面使用SurfaceView。

GLSurfaceView:基于SurfaceView視圖再次進(jìn)行拓展的視圖類(lèi),專(zhuān)用于3D游戲開(kāi)發(fā)的視圖;是SurfaceView的子類(lèi),openGL專(zhuān)用。
如何實(shí)現(xiàn)進(jìn)程保活

a: Service 設(shè)置成 START_STICKY kill 后會(huì)被重啟(等待5秒左右),重傳Intent,保持與重啟前一樣

b: 通過(guò) startForeground將進(jìn)程設(shè)置為前臺(tái)進(jìn)程, 做前臺(tái)服務(wù),優(yōu)先級(jí)和前臺(tái)應(yīng)用一個(gè)級(jí)別,除非在系統(tǒng)內(nèi)存非常缺,否則此進(jìn)程不會(huì)被 kill

c: 雙進(jìn)程Service: 讓2個(gè)進(jìn)程互相保護(hù)對(duì)方,其中一個(gè)Service被清理后,另外沒(méi)被清理的進(jìn)程可以立即重啟進(jìn)程

d: 用C編寫(xiě)守護(hù)進(jìn)程(即子進(jìn)程) : Android系統(tǒng)中當(dāng)前進(jìn)程(Process)fork出來(lái)的子進(jìn)程,被系統(tǒng)認(rèn)為是兩個(gè)不同的進(jìn)程。當(dāng)父進(jìn)程被殺死的時(shí)候,子進(jìn)程仍然可以存活,并不受影響(Android5.0以上的版本不可行)聯(lián)系廠商,加入白名單

e.鎖屏狀態(tài)下,開(kāi)啟一個(gè)一像素Activity
說(shuō)下冷啟動(dòng)與熱啟動(dòng)是什么,區(qū)別,如何優(yōu)化,使用場(chǎng)景等。
app冷啟動(dòng): 當(dāng)應(yīng)用啟動(dòng)時(shí),后臺(tái)沒(méi)有該應(yīng)用的進(jìn)程,這時(shí)系統(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給該應(yīng)用, 這個(gè)啟動(dòng)方式就叫做冷啟動(dòng)(后臺(tái)不存在該應(yīng)用進(jìn)程)。冷啟動(dòng)因?yàn)橄到y(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給它,所以會(huì)先創(chuàng)建和初始化Application類(lèi),再創(chuàng)建和初始化MainActivity類(lèi)(包括一系列的測(cè)量、布局、繪制),最后顯示在界面上。

app熱啟動(dòng): 當(dāng)應(yīng)用已經(jīng)被打開(kāi), 但是被按下返回鍵、Home鍵等按鍵時(shí)回到桌面或者是其他程序的時(shí)候,再重新打開(kāi)該app時(shí), 這個(gè)方式叫做熱啟動(dòng)(后臺(tái)已經(jīng)存在該應(yīng)用進(jìn)程)。熱啟動(dòng)因?yàn)闀?huì)從已有的進(jìn)程中來(lái)啟動(dòng),所以熱啟動(dòng)就不會(huì)走Application這步了,而是直接走M(jìn)ainActivity(包括一系列的測(cè)量、布局、繪制),所以熱啟動(dòng)的過(guò)程只需要?jiǎng)?chuàng)建和初始化一個(gè)MainActivity就行了,而不必創(chuàng)建和初始化Application

冷啟動(dòng)的流程

當(dāng)點(diǎn)擊app的啟動(dòng)圖標(biāo)時(shí),安卓系統(tǒng)會(huì)從Zygote進(jìn)程中fork創(chuàng)建出一個(gè)新的進(jìn)程分配給該應(yīng)用,之后會(huì)依次創(chuàng)建和初始化Application類(lèi)、創(chuàng)建MainActivity類(lèi)、加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity以及配置Activity層級(jí)上的一些屬性、再inflate布局、當(dāng)onCreate/onStart/onResume方法都走完了后最后才進(jìn)行contentView的measure/layout/draw顯示在界面上

冷啟動(dòng)的生命周期簡(jiǎn)要流程:

Application構(gòu)造方法 –> attachBaseContext()–>onCreate –>Activity構(gòu)造方法 –> onCreate() –> 配置主體中的背景等操作 –>onStart() –> onResume() –> 測(cè)量、布局、繪制顯示

冷啟動(dòng)的優(yōu)化主要是視覺(jué)上的優(yōu)化,解決白屏問(wèn)題,提高用戶(hù)體驗(yàn),所以通過(guò)上面冷啟動(dòng)的過(guò)程。能做的優(yōu)化如下:

減少 onCreate()方法的工作量

不要讓 Application 參與業(yè)務(wù)的操作

不要在 Application 進(jìn)行耗時(shí)操作

不要以靜態(tài)變量的方式在 Application 保存數(shù)據(jù)

減少布局的復(fù)雜度和層級(jí)

減少主線程耗時(shí)

為什么冷啟動(dòng)會(huì)有白屏黑屏問(wèn)題?原因在于加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity發(fā)生在inflate布局當(dāng)onCreate/onStart/onResume方法之前,而windowBackground背景被設(shè)置成了白色或者黑色,所以我們進(jìn)入app的第一個(gè)界面的時(shí)候會(huì)造成先白屏或黑屏一下再進(jìn)入界面。解決思路如下

1.給他設(shè)置 windowBackground 背景跟啟動(dòng)頁(yè)的背景相同,如果你的啟動(dòng)頁(yè)是張圖片那么可以直接給 windowBackground 這個(gè)屬性設(shè)置該圖片那么就不會(huì)有一閃的效果了

`

2.采用世面的處理方法,設(shè)置背景是透明的,給人一種延遲啟動(dòng)的感覺(jué)。,將背景顏色設(shè)置為透明色,這樣當(dāng)用戶(hù)點(diǎn)擊桌面APP圖片的時(shí)候,并不會(huì)"立即"進(jìn)入APP,而且在桌面上停留一會(huì),其實(shí)這時(shí)候APP已經(jīng)是啟動(dòng)的了,只是我們心機(jī)的把Theme里的windowBackground 的顏色設(shè)置成透明的,強(qiáng)行把鍋甩給了手機(jī)應(yīng)用廠商(手機(jī)反應(yīng)太慢了啦)

`

3.以上兩種方法是在視覺(jué)上顯得更快,但其實(shí)只是一種表象,讓?xiě)?yīng)用啟動(dòng)的更快,有一種思路,將 Application 中的不必要的初始化動(dòng)作實(shí)現(xiàn)懶加載,比如,在SpashActivity 顯示后再發(fā)送消息到 Application,去初始化,這樣可以將初始化的動(dòng)作放在后邊,縮短應(yīng)用啟動(dòng)到用戶(hù)看到界面的時(shí)間

Android 中的線程有那些,原理與各自特點(diǎn)

AsyncTask,HandlerThread,IntentService

AsyncTask原理:內(nèi)部是Handler和兩個(gè)線程池實(shí)現(xiàn)的,Handler用于將線程切換到主線程,兩個(gè)線程池一個(gè)用于任務(wù)的排隊(duì),一個(gè)用于執(zhí)行任務(wù),當(dāng)AsyncTask執(zhí)行execute方法時(shí)會(huì)封裝出一個(gè)FutureTask對(duì)象,將這個(gè)對(duì)象加入隊(duì)列中,如果此時(shí)沒(méi)有正在執(zhí)行的任務(wù),就執(zhí)行它,執(zhí)行完成之后繼續(xù)執(zhí)行隊(duì)列中下一個(gè)任務(wù),執(zhí)行完成通過(guò)Handler將事件發(fā)送到主線程。AsyncTask必須在主線程初始化,因?yàn)閮?nèi)部的Handler是一個(gè)靜態(tài)對(duì)象,在AsyncTask類(lèi)加載的時(shí)候他就已經(jīng)被初始化了。在Android3.0開(kāi)始,execute方法串行執(zhí)行任務(wù)的,一個(gè)一個(gè)來(lái),3.0之前是并行執(zhí)行的。如果要在3.0上執(zhí)行并行任務(wù),可以調(diào)用executeOnExecutor方法

HandlerThread原理:繼承自 Thread,start開(kāi)啟線程后,會(huì)在其run方法中會(huì)通過(guò)Looper 創(chuàng)建消息隊(duì)列并開(kāi)啟消息循環(huán),這個(gè)消息隊(duì)列運(yùn)行在子線程中,所以可以將HandlerThread 中的 Looper 實(shí)例傳遞給一個(gè) Handler,從而保證這個(gè) Handler 的 handleMessage 方法運(yùn)行在子線程中,Android 中使用 HandlerThread的一個(gè)場(chǎng)景就是 IntentService
IntentService原理:繼承自Service,它的內(nèi)部封裝了 HandlerThread 和Handler,可以執(zhí)行耗時(shí)任務(wù),同時(shí)因?yàn)樗且粋€(gè)服務(wù),優(yōu)先級(jí)比普通線程高很多,所以更適合執(zhí)行一些高優(yōu)先級(jí)的后臺(tái)任務(wù)

HandlerThread底層通過(guò)Looper消息隊(duì)列實(shí)現(xiàn)的,所以它是順序的執(zhí)行每一個(gè)任務(wù)。可以通過(guò)Intent的方式開(kāi)啟IntentService,IntentService通過(guò)handler將每一個(gè)intent加入HandlerThread子線程中的消息隊(duì)列,通過(guò)looper按順序一個(gè)個(gè)的取出并執(zhí)行,執(zhí)行完成后自動(dòng)結(jié)束自己,不需要開(kāi)發(fā)者手動(dòng)關(guān)閉

ANR的原因

1.耗時(shí)的網(wǎng)絡(luò)訪問(wèn)
2.大量的數(shù)據(jù)讀寫(xiě)
3.數(shù)據(jù)庫(kù)操作
4.硬件操作(比如camera)
5.調(diào)用thread的join()方法、sleep()方法、wait()方法或者等待線程鎖的時(shí)候
6.service binder的數(shù)量達(dá)到上限
7.system server中發(fā)生WatchDog ANR
8.service忙導(dǎo)致超時(shí)無(wú)響應(yīng)
9.其他線程持有鎖,導(dǎo)致主線程等待超時(shí)
10.其它線程終止或崩潰導(dǎo)致主線程一直等待

三級(jí)緩存原理

當(dāng) Android 端需要獲得數(shù)據(jù)時(shí)比如獲取網(wǎng)絡(luò)中的圖片,首先從內(nèi)存中查找(按鍵查找),內(nèi)存中沒(méi)有的再?gòu)拇疟P(pán)文件或sqlite中去查找,若磁盤(pán)中也沒(méi)有才通過(guò)網(wǎng)絡(luò)獲取

LruCache 底層實(shí)現(xiàn)原理:

LruCache 中 Lru 算法的實(shí)現(xiàn)就是通過(guò) LinkedHashMap 來(lái)實(shí)現(xiàn)的。LinkedHashMap 繼承于 HashMap,它使用了一個(gè)雙向鏈表來(lái)存儲(chǔ) Map中的Entry順序關(guān)系

對(duì)于get、put、remove等操作,LinkedHashMap除了要做HashMap做的事情,還做些調(diào)整Entry順序鏈表的工作。

LruCache中將LinkedHashMap的順序設(shè)置為L(zhǎng)RU順序來(lái)實(shí)現(xiàn)LRU緩存,每次調(diào)用get(也就是從內(nèi)存緩存中取圖片),則將該對(duì)象移到鏈表的尾端。
調(diào)用put插入新的對(duì)象也是存儲(chǔ)在鏈表尾端,這樣當(dāng)內(nèi)存緩存達(dá)到設(shè)定的最大值時(shí),將鏈表頭部的對(duì)象(近期最少用到的)移除。

說(shuō)下你對(duì) Collection 這個(gè)類(lèi)的理解。

Collection是集合框架的頂層接口,是存儲(chǔ)對(duì)象的容器,Colloction定義了接口的公用方法如add remove clear等等,它的子接口有兩個(gè),List和Set,List的特點(diǎn)有元素有序,元素可以重復(fù),元素都有索引(角標(biāo)),典型的有

Vector:內(nèi)部是數(shù)組數(shù)據(jù)結(jié)構(gòu),是同步的(線程安全的)。增刪查詢(xún)都很慢。

ArrayList:內(nèi)部是數(shù)組數(shù)據(jù)結(jié)構(gòu),是不同步的(線程不安全的)。替代了Vector。查詢(xún)速度快,增刪比較慢。

LinkedList:內(nèi)部是鏈表數(shù)據(jù)結(jié)構(gòu),是不同步的(線程不安全的)。增刪元素速度快。

而Set的是特點(diǎn)元素?zé)o序,元素不可以重復(fù)

HashSet:內(nèi)部數(shù)據(jù)結(jié)構(gòu)是哈希表,是不同步的。

Set集合中元素都必須是唯一的,HashSet作為其子類(lèi)也需保證元素的唯一性。

判斷元素唯一性的方式:

通過(guò)存儲(chǔ)對(duì)象(元素)的hashCode和equals方法來(lái)完成對(duì)象唯一性的。

如果對(duì)象的hashCode值不同,那么不用調(diào)用equals方法就會(huì)將對(duì)象直接存儲(chǔ)到集合中;

如果對(duì)象的hashCode值相同,那么需調(diào)用equals方法判斷返回值是否為true,
若為false, 則視為不同元素,就會(huì)直接存儲(chǔ);
若為true, 則視為相同元素,不會(huì)存儲(chǔ)。

如果要使用HashSet集合存儲(chǔ)元素,該元素的類(lèi)必須覆蓋hashCode方法和equals方法。一般情況下,如果定義的類(lèi)會(huì)產(chǎn)生很多對(duì)象,通常都需要覆蓋equals,hashCode方法。建立對(duì)象判斷是否相同的依據(jù)。
TreeSet:保證元素唯一性的同時(shí)可以對(duì)內(nèi)部元素進(jìn)行排序,是不同步的。

判斷元素唯一性的方式:

根據(jù)比較方法的返回結(jié)果是否為0,如果為0視為相同元素,不存;如果非0視為不同元素,則存。

TreeSet對(duì)元素的排序有兩種方式:

方式一:使元素(對(duì)象)對(duì)應(yīng)的類(lèi)實(shí)現(xiàn)Comparable接口,覆蓋compareTo方法。這樣元素自身具有比較功能。

方式二:使TreeSet集合自身具有比較功能,定義一個(gè)比較器Comparator,將該類(lèi)對(duì)象作為參數(shù)傳遞給TreeSet集合的構(gòu)造函數(shù)

說(shuō)下AIDL的使用與原理

可以圍繞aidl是安卓中的一種進(jìn)程間通信方式

說(shuō)下你對(duì)廣播的理解

說(shuō)下你對(duì)服務(wù)的理解,如何殺死一個(gè)服務(wù)。服務(wù)的生命周期(start與bind)。

其他

是否接觸過(guò)藍(lán)牙等開(kāi)發(fā)

設(shè)計(jì)一個(gè)ListView左右分頁(yè)排版的功能自定義View,說(shuō)出主要的方法。

說(shuō)下binder序列化與反序列化的過(guò)程,與使用過(guò)程

是否接觸過(guò)JNI/NDK,java如何調(diào)用C語(yǔ)言的方法

如何查看模擬器中的SP與SQList文件。如何可視化查看布局嵌套層數(shù)與加載時(shí)間。

你說(shuō)用的代碼管理工具什么,為什么會(huì)產(chǎn)生代碼沖突,該如何解決

說(shuō)下你對(duì)后臺(tái)的編程有那些認(rèn)識(shí),聊些前端那些方面的知識(shí)。

說(shuō)下你對(duì)線程池的理解,如何創(chuàng)建一個(gè)線程池與使用。

說(shuō)下你用過(guò)那些注解框架,他們的原理是什么。自己實(shí)現(xiàn)過(guò),或是理解他的工作過(guò)程嗎?

說(shuō)下java虛擬機(jī)的理解,回收機(jī)制,JVM是如何回收對(duì)象的,有哪些方法等

一些java與Android源碼相關(guān)知識(shí)等

大學(xué)成績(jī)

大學(xué)那些專(zhuān)業(yè),你哪方面學(xué)得好

單片機(jī),嵌入式,電子線路。

畢業(yè)設(shè)計(jì)什么,幾個(gè)人實(shí)現(xiàn)的,主要功能是什么

還有些其他硬件相關(guān)知識(shí)

自己的職業(yè)規(guī)劃與發(fā)展方向

閱讀更多

資本寒冬下的android面經(jīng)

Android自定義View——啥是佩奇?

Flutter終將逆襲!1.2版本發(fā)布,或?qū)⒔y(tǒng)一江湖

APK 的前世今生:從 Android 源碼到 apk 的編譯打包流程

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/73669.html

相關(guān)文章

  • 金三銀四,2019大廠Android高級(jí)工程師面試整理

    摘要:原文地址游客前言金三銀四,很多同學(xué)心里大概都準(zhǔn)備著年后找工作或者跳槽。最近有很多同學(xué)都在交流群里求大廠面試題。 最近整理了一波面試題,包括安卓JAVA方面的,目前大廠還是以安卓源碼,算法,以及數(shù)據(jù)結(jié)構(gòu)為主,有一些中小型公司也會(huì)問(wèn)到混合開(kāi)發(fā)的知識(shí),至于我為什么傾向于混合開(kāi)發(fā),我的一句話就是走上編程之路,將來(lái)你要學(xué)不僅僅是這些,豐富自己方能與世接軌,做好全棧的裝備。 原文地址:游客kutd...

    tracymac7 評(píng)論0 收藏0
  • 前端最強(qiáng)面經(jīng)匯總

    摘要:獲取的對(duì)象范圍方法獲取的是最終應(yīng)用在元素上的所有屬性對(duì)象即使沒(méi)有代碼,也會(huì)把默認(rèn)的祖宗八代都顯示出來(lái)而只能獲取元素屬性中的樣式。因此對(duì)于一個(gè)光禿禿的元素,方法返回對(duì)象中屬性值如果有就是據(jù)我測(cè)試不同環(huán)境結(jié)果可能有差異而就是。 花了很長(zhǎng)時(shí)間整理的前端面試資源,喜歡請(qǐng)大家不要吝嗇star~ 別只收藏,點(diǎn)個(gè)贊,點(diǎn)個(gè)star再走哈~ 持續(xù)更新中……,可以關(guān)注下github 項(xiàng)目地址 https:...

    wangjuntytl 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<