面試專題我放在git上了坟漱,地址Github 歡迎fork然后一起更新
1,低版本 SDK 實現(xiàn)高版本 api
兩種情況:
1) 一般很多高版本的新的API都會在兼容包里面找到替代的實現(xiàn)。比如fragment辨赐。Notification宣增,在v4兼容包里面有NotificationCompat類。5.0+出現(xiàn)的backgroundTint封断,minSdk小于5.0的話會包檢測錯誤斯辰,v4兼容包DrawableCompat類。
2) 沒有替代實現(xiàn)就自己手動實現(xiàn)坡疼。比如:控件的水波紋效果—第三方實現(xiàn)彬呻。或者直接在低版本去除這個效果。
3) 補(bǔ)充:如果設(shè)置了minSDK但是代碼里面使用了高版本的API闸氮,會出現(xiàn)檢測錯誤剪况。需要在代碼里面使用聲明編譯檢測策略,比如:@SuppressLint和@TargetApi注解提示編譯器編譯的規(guī)則蒲跨。@SuppressLint是忽略檢測译断;@TargetApi=23,會根據(jù)你函數(shù)里面使用的API或悲,嚴(yán)格地匹配SDK版本孙咪,給出相應(yīng)的編譯錯誤提示。
4) 為了避免位置的錯誤隆箩,最好不要使用廢棄api该贾。(一般情況下不會有兼容性問題,后面可能會隨時刪除這個API方法捌臊;性能方面的問題杨蛋。)
5) http://chinagdg.org/2016/01/picking-your-compilesdkversion-minsdkversion-targetsdkversion/
2,Android 的安全問題理澎?
1逞力,參數(shù)校驗不嚴(yán)格
2,webview 引入js注入
3糠爬,明文存儲寇荧,山寨加密
4,濫用權(quán)限执隧,內(nèi)存泄露揩抡,使用debug簽名
5,不混淆镀琉,不防二次打包峦嗤,不加固等
3,Android與服務(wù)器交互的加密方式
對稱加密屋摔,AES烁设,DES,加密解密用的key是一樣的钓试。
非對稱加密装黑,RSA,加密解密使用的不同的key弓熏,發(fā)送數(shù)據(jù)之前要先和服務(wù)端約定生成公鑰和私鑰恋谭,使用公鑰加密的數(shù)據(jù)可以用私鑰解密,ssh和ssl都是典型的非對稱加密硝烂。
對極大整數(shù)做因數(shù)分解的難度決定了RSA的算法的可靠性箕别;對一個極大整數(shù)做因數(shù)分解越困難铜幽,RSA算法就越可靠。
如何破解RSA算法串稀,除非你能找到一種快速因數(shù)分解的算法除抛,否則破解的可能非常小
4,Android下解決滑動沖突的常見思路是什么母截?
相關(guān)的滑動組件到忽,重寫onInterceptTouchEvent,然后判斷根據(jù)XY值清寇,來決定是否要攔截當(dāng)前操作
5喘漏,Android 為每個應(yīng)用程序分配的內(nèi)存大小是多少?
看具體的手機(jī)平臺华烟,常見的有:64M/32M等
6翩迈,App啟動流程
App啟動時,AMS會檢查這個應(yīng)用程序所需要的進(jìn)程是否存在盔夜,不存在就會請求Zygote進(jìn)程啟動需要的應(yīng)用程序進(jìn)程负饲,
Zygote進(jìn)程接收到AMS請求并通過fock自身創(chuàng)建應(yīng)用程序進(jìn)程,這樣應(yīng)用程序進(jìn)程就會獲取虛擬機(jī)的實例喂链,還會創(chuàng)建Binder線程池(ProcessState.startThreadPool())和消息循環(huán)(ActivityThread looper.loop),
然后App進(jìn)程返十,通過Binder IPC向sytem_server進(jìn)程發(fā)起attachApplication請求;
system_server進(jìn)程在收到請求后椭微,進(jìn)行一系列準(zhǔn)備工作后洞坑,再通過Binder IPC向App進(jìn)程發(fā)送scheduleLaunchActivity請求;
App進(jìn)程的binder線程(ApplicationThread)在收到請求后蝇率,通過handler向主線程發(fā)送LAUNCH_ACTIVITY消息迟杂;
主線程在收到Message后,通過反射機(jī)制創(chuàng)建目標(biāo)Activity本慕,并回調(diào)Activity.onCreate()等方法逢慌。
到此,App便正式啟動间狂,開始進(jìn)入Activity生命周期,執(zhí)行完onCreate/onStart/onResume方法火架,UI渲染結(jié)束后便可以看到App的主界面鉴象。
7, 說下冷啟動與熱啟動是什么何鸡,區(qū)別纺弊,如何優(yōu)化,使用場景等骡男。
app冷啟動: 當(dāng)應(yīng)用啟動時淆游,后臺沒有該應(yīng)用的進(jìn)程,這時系統(tǒng)會重新創(chuàng)建一個新的進(jìn)程分配給該應(yīng)用, 這個啟動方式就叫做冷啟動(后臺不存在該應(yīng)用進(jìn)程)犹菱。冷啟動因為系統(tǒng)會重新創(chuàng)建一個新的進(jìn)程分配給它拾稳,所以會先創(chuàng)建和初始化Application類,再創(chuàng)建和初始化MainActivity類(包括一系列的測量腊脱、布局访得、繪制),最后顯示在界面上陕凹。
app熱啟動: 當(dāng)應(yīng)用已經(jīng)被打開悍抑, 但是被按下返回鍵、Home鍵等按鍵時回到桌面或者是其他程序的時候杜耙,再重新打開該app時搜骡, 這個方式叫做熱啟動(后臺已經(jīng)存在該應(yīng)用進(jìn)程)。熱啟動因為會從已有的進(jìn)程中來啟動佑女,所以熱啟動就不會走Application這步了记靡,而是直接走M(jìn)ainActivity(包括一系列的測量、布局珊豹、繪制)簸呈,所以熱啟動的過程只需要創(chuàng)建和初始化一個MainActivity就行了,而不必創(chuàng)建和初始化Application
冷啟動的流程
當(dāng)點擊app的啟動圖標(biāo)時店茶,安卓系統(tǒng)會從Zygote進(jìn)程中fork創(chuàng)建出一個新的進(jìn)程分配給該應(yīng)用蜕便,之后會依次創(chuàng)建和初始化Application類、創(chuàng)建MainActivity類贩幻、加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity以及配置Activity層級上的一些屬性轿腺、再inflate布局、當(dāng)onCreate/onStart/onResume方法都走完了后最后才進(jìn)行contentView的measure/layout/draw顯示在界面上
冷啟動的生命周期簡要流程:
Application構(gòu)造方法 –> attachBaseContext()–>onCreate –>Activity構(gòu)造方法 –> onCreate() –> 配置主體中的背景等操作 –>onStart() –> onResume() –> 測量丛楚、布局族壳、繪制顯示
冷啟動的優(yōu)化主要是視覺上的優(yōu)化,解決白屏問題趣些,提高用戶體驗仿荆,所以通過上面冷啟動的過程。能做的優(yōu)化如下:
1坏平、減少onCreate()方法的工作量
2拢操、不要讓Application參與業(yè)務(wù)的操作
3、不要在Application進(jìn)行耗時操作
4舶替、不要以靜態(tài)變量的方式在Application保存數(shù)據(jù)
5令境、減少布局的復(fù)雜度和層級
6、減少主線程耗時
8顾瞪,為什么冷啟動會有白屏黑屏問題舔庶?
原因在于加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity發(fā)生在inflate布局當(dāng)onCreate/onStart/onResume方法之前抛蚁,而windowBackground背景被設(shè)置成了白色或者黑色,所以我們進(jìn)入app的第一個界面的時候會造成先白屏或黑屏一下再進(jìn)入界面惕橙。解決思路如下
1.給他設(shè)置windowBackground背景跟啟動頁的背景相同瞧甩,如果你的啟動頁是張圖片那么可以直接給windowBackground這個屬性設(shè)置該圖片那么就不會有一閃的效果了
<style name="Splash_Theme" parent="@android:style/Theme.NoTitleBar">
<item name="android:windowBackground">@drawable/splash_bg</item>
<item name="android:windowNoTitle">true</item>
2.采用市面上的處理方法,設(shè)置背景是透明的吕漂,給人一種延遲啟動的感覺亲配。,將背景顏色設(shè)置為透明色,這樣當(dāng)用戶點擊桌面APP圖片的時候,并不會"立即"進(jìn)入APP惶凝,而且在桌面上停留一會吼虎,其實這時候APP已經(jīng)是啟動的了,只是我們心機(jī)的把Theme里的windowBackground的顏色設(shè)置成透明的苍鲜,強(qiáng)行把鍋甩給了手機(jī)應(yīng)用廠商(手機(jī)反應(yīng)太慢了啦)
<style name="Splash_Theme" parent="@android:style/Theme.NoTitleBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
3.以上兩種方法是在視覺上顯得更快思灰,但其實只是一種表象,讓應(yīng)用啟動的更快混滔,有一種思路洒疚,將Application中的不必要的初始化動作實現(xiàn)懶加載,比如坯屿,在SpashActivity顯示后再發(fā)送消息到Application油湖,去初始化,這樣可以將初始化的動作放在后邊领跛,縮短應(yīng)用啟動到用戶看到界面的時間
9乏德,Android單線程模型
Android單線程模型的核心原則就是:只能在UI線程(Main Thread)中對UI進(jìn)行處理。當(dāng)一個程序第一次啟動時吠昭,Android會同時啟動一個對應(yīng)的 主線程(Main Thread)喊括,主線程主要負(fù)責(zé)處理與UI相關(guān)的事件,如:用戶的按鍵事件矢棚,用戶接觸屏幕的事件以及屏幕繪圖事件郑什,并把相關(guān)的事件分發(fā)到對應(yīng)的組件進(jìn)行處理。所以主線程通常又被叫做UI線程蒲肋。在開發(fā)Android應(yīng)用時必須遵守單線程模型的原則: Android UI操作并不是線程安全的并且這些操作必須在UI線程中執(zhí)行蘑拯。
Android的單線程模型有兩條原則:
1.不要阻塞UI線程。
2.不要在UI線程之外訪問Android UI toolkit(主要是這兩個包中的組件:android.widget and android.view
10兜粘,Java虛擬機(jī)和Dalvik虛擬機(jī)的區(qū)別
Java虛擬機(jī):
1强胰、java虛擬機(jī)基于棧。 基于棧的機(jī)器必須使用指令來載入和操作棧上數(shù)據(jù)妹沙,所需指令更多更多。
2熟吏、java虛擬機(jī)運(yùn)行的是java字節(jié)碼距糖。(java類會被編譯成一個或多個字節(jié)碼.class文件)
Dalvik虛擬機(jī):
1玄窝、dalvik虛擬機(jī)是基于寄存器的
2、Dalvik運(yùn)行的是自定義的.dex字節(jié)碼格式悍引。(java類被編譯成.class文件后恩脂,會通過一個dx工具將所有的.class文件轉(zhuǎn)換成一個.dex文件,然后dalvik虛擬機(jī)會從其中讀取指令和數(shù)據(jù)
3趣斤、常量池已被修改為只使用32位的索引俩块,以 簡化解釋器。
4浓领、一個應(yīng)用玉凯,一個虛擬機(jī)實例,一個進(jìn)程(所有android應(yīng)用的線程都是對應(yīng)一個linux線程联贩,都運(yùn)行在自己的沙盒中漫仆,不同的應(yīng)用在不同的進(jìn)程中運(yùn)行。每個android dalvik應(yīng)用程序都被賦予了一個獨立的linux PID(app_*))