APK安裝過程
應(yīng)用安裝涉及到如下幾個目錄:
- system/app:系統(tǒng)自帶的應(yīng)用程序元媚,無法刪除
- data/app:用戶程序安裝的目錄舀奶,有刪除權(quán)限得糜。安裝時把apk文件復(fù)制到此目錄
- data/data:存放應(yīng)用程序的數(shù)據(jù)
- data/dalvik-cache:將apk中的dex文件安裝到dalvik-cache目錄下
復(fù)制APK安裝包到data/app目錄下,解壓并掃描安裝包粥诫,把dex文件(Dalvik字節(jié)碼)保存到dalvik-cache目錄,并在data/data目錄下創(chuàng)建對應(yīng)的應(yīng)用數(shù)據(jù)目錄卢鹦。
invalidate()和postInvalidate() 的區(qū)別
- invalidate()是用來刷新View的臀脏,必須是在UI線程中進行工作。比如在修改某個view的顯示時冀自,調(diào)用invalidate()才能看到重新繪制的界面揉稚。
- postInvalidate()在工作者線程中被調(diào)用。
導入外部數(shù)據(jù)庫
Android系統(tǒng)下數(shù)據(jù)庫應(yīng)該存放在 /data/data/com..(package name)/ 目錄下熬粗,所以我們需要做的是把已有的數(shù)據(jù)庫傳入那個目錄下搀玖。操作方法是用FileInputStream讀取原數(shù)據(jù)庫,再用FileOutputStream把讀取到的東西寫入到那個目錄驻呐。
Parcelable和Serializable區(qū)別
Parcelable的性能比Serializable好灌诅,在內(nèi)存開銷方面較小,所以在內(nèi)存間數(shù)據(jù)傳輸時推薦使用Parcelable含末,如activity間傳輸數(shù)據(jù)猜拾,而Serializable可將數(shù)據(jù)持久化方便保存,所以在需要保存或網(wǎng)絡(luò)傳輸數(shù)據(jù)時選擇Serializable佣盒,因為android不同版本Parcelable可能不同挎袜,所以不推薦使用Parcelable進行數(shù)據(jù)持久化。
Serializable序列化不保存靜態(tài)變量,可以使用Transient關(guān)鍵字對部分字段不進行序列化盯仪,也可以覆蓋writeObject紊搪、readObject方法以實現(xiàn)序列化過程自定義。
Android里跨進程傳遞數(shù)據(jù)的幾種方案
- Binder
- Socket/LocalSocket
- 共享內(nèi)存
匿名共享內(nèi)存全景,使用場景
在Android系統(tǒng)中耀石,提供了獨特的匿名共享內(nèi)存子系統(tǒng)Ashmem(Anonymous Shared Memory),它以驅(qū)動程序的形式實現(xiàn)在內(nèi)核空間中爸黄。它有兩個特點滞伟,一是能夠輔助內(nèi)存管理系統(tǒng)來有效地管理不再使用的內(nèi)存塊,二是它通過Binder進程間通信機制來實現(xiàn)進程間的內(nèi)存共享炕贵。
ashmem并像Binder是Android重新自己搞的一套東西诗良,而是利用了Linux的 tmpfs文件系統(tǒng)。tmpfs是一種可以基于RAM或是SWAP的高速文件系統(tǒng)鲁驶,然后可以拿它來實現(xiàn)不同進程間的內(nèi)存共享鉴裹。
大致思路和流程是:
- Proc A 通過 tmpfs 創(chuàng)建一塊共享區(qū)域,得到這塊區(qū)域的 fd(文件描述符)
- Proc A 在 fd 上 mmap 一片內(nèi)存區(qū)域到本進程用于共享數(shù)據(jù)
- Proc A 通過某種方法把 fd 倒騰給 Proc B
- Proc B 在接到的 fd 上同樣 mmap 相同的區(qū)域到本進程
- 然后 A钥弯、B 在 mmap 到本進程中的內(nèi)存中讀径荔、寫,對方都能看到了
其實核心點就是 創(chuàng)建一塊共享區(qū)域脆霎,然后2個進程同時把這片區(qū)域 mmap 到本進程总处,然后讀寫就像本進程的內(nèi)存一樣。這里要解釋下第3步睛蛛,為什么要倒騰 fd鹦马,因為在 linux 中 fd 只是對本進程是唯一的,在 Proc A 中打開一個文件得到一個 fd忆肾,但是把這個打開的 fd 直接放到 Proc B 中荸频,Proc B 是無法直接使用的。但是文件是唯一的客冈,就是說一個文件(file)可以被打開多次旭从,每打開一次就有一個 fd(文件描述符),所以對于同一個文件來說场仲,需要某種轉(zhuǎn)化和悦,把 Proc A 中的 fd 轉(zhuǎn)化成 Proc B 中的 fd。這樣 Proc B 才能通過 fd mmap 同樣的共享內(nèi)存文件渠缕。
使用場景:進程間大量數(shù)據(jù)傳輸鸽素。
ContentProvider實現(xiàn)原理
ContentProvider 有以下兩個特點:
- 封裝:對數(shù)據(jù)進行封裝,提供統(tǒng)一的接口亦鳞,使用者完全不必關(guān)心這些數(shù)據(jù)是在DB馍忽,XML澜汤、Preferences或者網(wǎng)絡(luò)請求來的。當項目需求要改變數(shù)據(jù)來源時舵匾,使用我們的地方完全不需要修改。
- 提供一種跨進程數(shù)據(jù)共享的方式谁不。
Content Provider組件在不同應(yīng)用程序之間傳輸數(shù)據(jù)是基于匿名共享內(nèi)存機制來實現(xiàn)的坐梯。其主要的調(diào)用過程:
- 通過ContentResolver先查找對應(yīng)給定Uri的ContentProvider,返回對應(yīng)的BinderProxy
-
如果該Provider尚未被調(diào)用進程使用過:
- 通過ServiceManager查找activity service得到ActivityManagerService對應(yīng)BinderProxy
- 調(diào)用BinderProxy的transcat方法發(fā)送GET_CONTENT_PROVIDER_TRANSACTION命令刹帕,得到對應(yīng)ContentProvider的BinderProxy吵血。
如果該Provider已被調(diào)用進程使用過,則調(diào)用進程會保留使用過provider的HashMap偷溺。此時直接從此表查詢即得蹋辅。
- 調(diào)用BinderProxy的query()
如何使用ContentProvider進行批量操作?
通常進行數(shù)據(jù)的批量操作我們都會使用“事務(wù)”挫掏,但是ContentProvider如何進行批量操作呢侦另?創(chuàng)建 ContentProviderOperation 對象數(shù)組,然后使用 ContentResolver.applyBatch() 將其分派給內(nèi)容提供程序尉共。您需將內(nèi)容提供程序的授權(quán)傳遞給此方法褒傅,而不是特定內(nèi)容 URI。這樣可使數(shù)組中的每個 ContentProviderOperation 對象都能適用于其他表袄友。調(diào)用 ContentResolver.applyBatch() 會返回結(jié)果數(shù)組殿托。
同時我們還可以通過ContentObserver對數(shù)據(jù)進行觀察:
- 創(chuàng)建我們特定的ContentObserver派生類,必須重載onChange()方法去處理回調(diào)后的功能實現(xiàn)
- 利用context.getContentResolover()獲得ContentResolove對象剧蚣,接著調(diào)用registerContentObserver()方法去注冊內(nèi)容觀察者支竹,為指定的Uri注冊一個ContentObserver派生類實例,當給定的Uri發(fā)生改變時鸠按,回調(diào)該實例對象去處理礼搁。
- 由于ContentObserver的生命周期不同步于Activity和Service等,因此目尖,在不需要時叹坦,需要手動的調(diào)用unregisterContentObserver()去取消注冊。
Application類的作用
Android系統(tǒng)會為每個程序運行時創(chuàng)建一個Application類的對象且僅創(chuàng)建一個卑雁,所以Application可以說是單例 (singleton)模式的一個類募书。Application對象的生命周期是整個程序中最長的,它的生命周期就等于這個程序的生命周期测蹲。因為它是全局的單例的莹捡,所以在不同的Activity,Service中獲得的對象都是同一個對象。所以通過Application來進行一些扣甲,數(shù)據(jù)傳遞篮赢,數(shù)據(jù)共享齿椅,數(shù)據(jù)緩存等操作。
廣播注冊后不解除注冊會有什么問題启泣?(內(nèi)存泄露)
我們可以通過兩種方式注冊BroadcastReceiver涣脚,一是在Activity啟動過程中通過代碼動態(tài)注冊,二是在AndroidManifest.xml文件中利用<receiver>標簽進行靜態(tài)注冊寥茫。
- 對于第一種方法遣蚀,我們需要養(yǎng)成一個良好的習慣:在Activity進入停止或者銷毀狀態(tài)的時候使用unregisterReceiver方法將注冊的BroadcastReceiver注銷掉。
- 對于<receiver>標簽進行注冊的纱耻,那么該對象的實例在onReceive被調(diào)用之后就會在任意時間內(nèi)被銷毀芭梯。
屬性動畫(Property Animation)和補間動畫(Tween Animation)的區(qū)別
- 補間動畫只是針對于View,超脫了View就無法操作了弄喘。
- 補間動畫有四種動畫操作(移動玖喘,縮放,旋轉(zhuǎn)蘑志,淡入淡出)累奈。
- 補間動畫只是改變View的顯示效果而已,但是不會真正的去改變View的屬性急但。
- 屬性動畫改變View的實際屬性值费尽,當然它也可以不作用于View。
BrocastReceive里面可不可以執(zhí)行耗時操作?
不能羊始,當 onReceive() 方法在 10 秒內(nèi)沒有執(zhí)行完畢旱幼,Android 會認為該程序無響應(yīng),所以在BroadcastReceiver里不能做一些比較耗時的操作突委,否側(cè)會彈出 ANR 的對話框柏卤。
文末送福利啦!匀油!
我總結(jié)出了互聯(lián)網(wǎng)公司Android程序員面試涉及到的絕大部分面試題及答案缘缚,并整理做成了文檔,以及系統(tǒng)的進階學習視頻資料敌蚜,免費分享給大家桥滨。
(包括Java在Android開發(fā)中應(yīng)用、APP框架知識體系弛车、高級UI齐媒、全方位性能調(diào)優(yōu),NDK開發(fā)纷跛,音視頻技術(shù)喻括,人工智能技術(shù),跨平臺技術(shù)等技術(shù)資料)贫奠,希望能幫助到你面試前的復(fù)習唬血,且找到一個好的工作望蜡,也節(jié)省大家在網(wǎng)上搜索資料的時間來學習。
資料領(lǐng)取方式:點擊鏈接加入群聊【Android開發(fā)交流】:https://jq.qq.com/?_wv=1027&k=57fcAxd拷恨,找群管理免費領(lǐng)取脖律。備注一下簡書看到的來領(lǐng)取資料就可以了!