[TOC]
## 四大組件
### Acvitiy
#### Activity生命周期

* 每一個生命周期對應的過程
* onCreate:Activity正在創建。適合做一些初始化工作,初始化Activity所需要的數據等。
* onStart:Activity正在被啟動,即將開始,這時Activity已經可見,但是還沒有出現在前臺,還無法和用戶交互。可以理解為這個時候Activity已經出來了,但是我們還看不到
* onResume:此時Activity已經對用戶可見,并且出現在前臺開始活動。
* onPause:表示Activity正在停止,正常情況下緊接著onStop就會被調用。此時可以做一些輕量級的操作,不能太耗時。否則會影響到新的Activity的顯示,onPause必須先執行完,新Activity的onResume才回執行。
* onStop:表示Activity即將停止,可以做一些稍微重量級的回收工作,同樣不能太耗時。
* onDestroy:表示Activity即將唄銷毀,這是Activity生命周期中的最后一個回調,在這里可以做一些回收工作和最終的資源釋放。
* onRestart:Activity從不可見變為可見狀態時調用。
* 常見情況分析
* Activity第一次啟動:onCreate->onStart->onResume
* 鎖屏或者按Home鍵:onPause->onStop
* 解鎖:onRestart->onStart->onResume
* AActivity啟動BActivity(正常Activity):A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop(如果B是透明的,則沒有onStop這一步驟)
* 按back退出:onPause->onStop->onDestroy
* 總結
* onCreate和onDestroy是一對,onStart和onStop是一對,onResume和onPause是一對
#### Activity啟動模式分析
如何查看Activity棧:
adb shell dumpsys activity

* standard模式:
每啟動一次Activity,就會創建一個新的Activity實例并置于棧頂。誰啟動了這個Activity,那么這個Activity就運行在啟動它的那個Activity所在的棧中。
例如:Activity A啟動了Activity B,則就會在A所在的棧頂壓入一個新的Activity。

特殊情況:如果再Service或者Application中啟動一個Acitivty,并沒有所謂的任務棧,會報錯可以使用標記位Flag來解決,為啟動的Activity指定FLAG_ACTIVITY_NEW_TASK標記位,創建一個新棧。
* singletop模式:
在這個模式中,Activity還是會創建在啟動它的Activity的任務棧中,但是如果它已經位于棧頂,那么就不會重復創建,并且它的onNewIntent會被調用,但是要注意它的生命周期方法onCreate等等不會創建。并且如果它并不位于棧頂,如ABC,這時啟動B,還是會創建一個新的實例。
* singletask模式:
在這個模式中,比如啟動Activity A,首先系統會尋找是否存在A想要的任務棧:
如果存在,就看任務棧中是否有A,如果有就有clearTop的效果,把A推到棧頂,并且調用onNewIntent,即CABD的任務棧,clearTop之后就是CA;如果沒有A,就創建A在棧頂。并且要注意一點,如果存在A的任務棧,那么任務棧自動回切換到前臺,如下圖所示:

Y的任務棧直接被切換到了前臺,這點和微信的聊天界面是一樣的。
如果不存在,就創建A所需要的任務棧并且創建A入棧。
**使用場景:**
一般來說棧內復用適用于在一個應用里我們希望唯一存在的界面,比如聊天界面,比如微信的聊天界面,我們在一個聊天界面點擊了頭像進入了新的界面,這個時候來了一條新的消息并且用戶點擊了消息,這個時候如果是Standard模式就會創建一個新的實例,這樣用戶在新的界面點擊back,用戶期望回到的是主界面,而實際上回到了之前的頭像界面,這就不符合常規了。如果把聊天設為棧內唯一模式,那么用戶點擊之后就會回到之前的聊天界面并且做一些改變,保證了聊天界面的唯一性。瀏覽器的例子也是這樣,我們肯定希望瀏覽器瀏覽的界面是唯一的,也需要用到這個模式。
**TaskAffinity:**https://juejin.im/post/5935081d2f301e006b09cb9e
* singleInstance模式:
單實例模式。啟動的時候無論從哪里啟動都會創建一個唯一的任務棧,后續的創建都不會再創建新的Activity繼續復用該Activity同時回調onNewIntent方法,除非該Activity被銷毀了。
singleInstace與singleTask的區別在于:singleTask啟動的Activity在系統層面上來說是可以有多個實例的。比如說應用程序A想調用singleTask模式下的ActivityA,而應用程序B也同樣調用了,那么在應用程序A和B中就會各有一個ActivityA的實例。但如果該ActivityA是singleInstance模式的話,那么無論有多少個應用程序調用它,它都只可能在系統中存在一個實例同時該實例還是位于它自己的一個單獨的任務棧中。

**應用場景:**呼叫來電界面。這種模式的使用情況比較罕見,在Launcher中可能使用。或者你確定你需要使Activity只有一個實例。建議謹慎使用。
#### Activity啟動流程
[3分鐘看懂Activity啟動流程](https://www.jianshu.com/p/9ecea420eb52)

整個流程涉及的主要角色有:
* Instrumentation: 監控應用與系統相關的交互行為。
* AMS:組件管理調度中心,什么都不干,但是什么都管。
* ActivityStarter:Activity啟動的控制器,處理Intent與Flag對Activity啟動的影響,具體說來有:1 尋找符合啟動條件的Activity,如果有多個,讓用戶選擇;2 校驗啟動參數的合法性;3 返回int參數,代表Activity是否啟動成功。
* ActivityStackSupervisior:這個類的作用你從它的名字就可以看出來,它用來管理任務棧。
* ActivityStack:用來管理任務棧里的Activity。
* ActivityThread:最終干活的人,是ActivityThread的內部類,Activity、Service、BroadcastReceiver的啟動、切換、調度等各種操作都在這個類里完成。
注:這里單獨提一下ActivityStackSupervisior,這是高版本才有的類,它用來管理多個ActivityStack,早期的版本只有一個ActivityStack對應著手機屏幕,后來高版本支持多屏以后,就 有了多個ActivityStack,于是就引入了ActivityStackSupervisior用來管理多個ActivityStack。
整個流程主要涉及四個進程:
* 調用者進程,如果是在桌面啟動應用就是Launcher應用進程。
* ActivityManagerService等所在的System Server進程,該進程主要運行著系統服務組件。
* Zygote進程,該進程主要用來fork新進程。
* 新啟動的應用進程,該進程就是用來承載應用運行的進程了,它也是應用的主線程(新創建的進程就是主線程),處理組件生命周期、界面繪制等相關事情。
有了以上的理解,整個流程可以概括如下:
1. 點擊桌面應用圖標,Launcher進程將啟動Activity(MainActivity)的請求以Binder的方式發送給了AMS。
2. AMS接收到啟動請求后,交付ActivityStarter處理Intent和Flag等信息,然后再交給ActivityStackSupervisior/ActivityStack 處理Activity進棧相關流程。同時以Socket方式請求Zygote進程fork新進程。
3. Zygote接收到新進程創建請求后fork出新進程。
4. 在新進程里創建ActivityThread對象,新創建的進程就是應用的主線程,在主線程里開啟Looper消息循環,開始處理創建Activity。
5. ActivityThread利用ClassLoader去加載Activity、創建Activity實例,并回調Activity的onCreate()方法。這樣便完成了Activity的啟動。
### AMS是怎么找到啟動的那個activity的?
#### 保存Activity的狀態以及onSaveInstanceState原理分析
[Android狀態保存與恢復流程完全解析](https://mp.weixin.qq.com/s?src=11×tamp=1548662220&ver=1393&signature=xOmN4*hyWgvJrBnpgnLhoImzDuEKdrGoNnHIibhN-R*7pxpaGdGmeJyZNno4clTGYZr7T0SjNJ7xheUdKE0hNwT2vjtlmX8ZAEZ-soXGae9JmTZ0iaFbRktSmA2N9Fsq&new=1)
### Serivce
#### Service生命周期(注意bindService和startService之間生命周期的不同)
* (1)startService()

* (2)stopService()

* (3)bindService()

* (4)unbindService()

* (5)只使用startService啟動服務的生命周期

* (6)只使用BindService綁定生命周期服務

* (7)同時使用startService()啟動服務、BindService()綁定服務的生命周期

#### Service先start再bind如何關閉service,為什么bindService可以跟Activity生命周期聯動?
#### Service 與 IntentService 的區別
#### Activity如何與Service通信?
### BroadCast
#### 廣播分為哪幾種,應用場景是什么?
* 普通廣播
即開發者自身定義intent的廣播(最常用)
* 系統廣播
Android系統內置的廣播,例如開機、網絡狀態變化等都會發出響應廣播,這些廣播都有對應的intent-filter。
* 有序廣播
* 1.按照Priority屬性值從大到小排序
* 2.Priority屬性相同者,動態注冊的廣播優先。
接收廣播按順序接收。先接收的廣播接受者可以對廣播進行截斷,即后接受的廣播接受者不再接收此廣播。同時先接收的廣播可以對廣播進行修改,后接受的廣播接受者接受到的就是修改后的廣播。
* 粘性廣播
Android5.0中已經失效,不建議使用。
* App應用內廣播
Android中的廣播可以跨App直接通信(exported對于有intent-filter情況下默認值為true),這樣會導致其他App針對性發出當前App相匹配的廣播,導致當前App不斷接受廣播并處理出現安全性、效率問題。
應用內廣播(LocalBroadcast)可以理解成為一種局部廣播,廣播的發送者和接受者都只能是當前App,這樣使得廣播的安全性以及效率更高。
#### 廣播的兩種注冊方式有什么區別?
* 1.代碼中動態注冊
* 2.在Manifest.xml中靜態注冊
第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。第二種是常駐型,也就是說程序關閉后,如果有信息廣播來,程序也會被系統調用運行。
#### 廣播發送和接收的原理了解嗎?
Android中的廣播使用了設計模式中的觀察者模式,基于消息的發布/訂閱事件模型。
具體實現流程概括如下:
- 1.自定義廣播接受者BroadcastReceiver,并復寫onReceive()方法
- 2.通過Binder機制向AMS進行注冊
- 3.廣播發送者通過Binder機制向AMS發送廣播
- 4.AMS查找復合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到BroadcastReceiver相應的消息循環隊列中。
- 5.消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法
#### 廣播傳輸的數據是否有限制,是多少,為什么要限制?
廣播是通過Intent攜帶要傳遞的數據的。Intent是通過Binder機制實現的,Binder對數據大小有限制,不同ROM不一樣,一般是1M。Binder在通信過程當中,會發生一次內存拷貝,顯示,傳輸的數據越小效率越高。
#### BroadcastReceiver與LocalBroadcastReceiver有什么區別?
* BroadcastReceiver是跨應用廣播,利用Binder機制實現。
* LocalBroadCastReceiver是應用內廣播,利用Handler實現,利用了IntentFilter的match功能,提供消息的發布與接收功能,實現應用內通信,效率較高。
### 跨域廣播也是觀察者模式嗎?
### 兩個應用同時注冊一個廣播,優先級都一樣,哪個會先收到廣播?(有序廣播?)
### ContentProvider
#### ContentProvider、ContentResolver與ContentObserver之間的關系是什么?
### contenprovider已經是進程間通信,為什么還要引入broadcastreceiver?
## Fragment
### Fragment生命周期
[Fragments: The Solution to All of Android's Problems](https://academy.realm.io/posts/michael-yotive-state-of-fragments-2017/)
[Android基礎:Fragment,看這篇就夠了](https://cloud.tencent.com/developer/article/1071779)
[我為什么主張反對使用Android Fragment](https://asce1885.gitbooks.io/android-rd-senior-advanced/content/wo_wei_shi_yao_zhu_zhang_fan_dui_shi_yong_android_fragment.html)


### getActivity()空指針問題
### Fragment視圖重疊
### Fragment之間如何通信
### Fragment 和 Activity 有什么區別?它們之間又有什么關系?
## View
### View繪制流程
[Android View的繪制流程](https://jsonchao.github.io/2018/10/28/Android%20View%E7%9A%84%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B/)
[Android應用層View繪制流程與源碼分析](https://blog.csdn.net/yanbober/article/details/46128379)
[淺析Android View內部工作原理及其實戰](https://blog.csdn.net/AndrExpert/article/details/77511996)
### 描述一下Android的事件分發機制?
[Android觸摸事件傳遞機制](https://jsonchao.github.io/2018/10/17/Android%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E4%BC%A0%E9%80%92%E6%9C%BA%E5%88%B6/)
[【透鏡系列】看穿 > 觸摸事件分發 >](https://juejin.im/post/5c3c8538f265da6142741d63)
[Android事件分發機制學習筆記](https://zhuanlan.zhihu.com/p/27608989)
[可能是講解Android事件分發最好的文章](https://www.jianshu.com/p/2be492c1df96)
### 計算viewgroup的層級,遞歸實現和非遞歸實現
### 在onCreate里面可以得到view的寬高嗎?
### view的getWidth和getMeasureWidth有啥區別?
### Scroller使用原理
### 動畫有哪幾類,各有什么特點
* 視圖動畫(View 動畫)
* 幀動畫(Frame 動畫、Drawable 動畫)
* 屬性動畫
* 觸摸反饋動畫(Ripple Effect)
* 揭露動畫(Reveal Effect)
* 轉場動畫 & 共享元素(Activity 切換動畫)
* 視圖狀態動畫(Animate View State Changes)
* 矢量圖動畫(Vector 動畫)
* 約束布局實現的關鍵幀動畫(ConstraintSet 動畫)
[Android 一共有多少種動畫?準確告訴你!](https://www.jianshu.com/p/0eb89d43eea4)
### PopupWindow和Dialog的區別
### Activity、Window、View的關系

[Activity、View、Window的理解一篇文章就夠了](https://juejin.im/entry/596329686fb9a06bc903b6fd)
[Android視圖框架Activity,Window,View,ViewRootImpl理解](https://silencedut.github.io/2016/08/10/Android%E8%A7%86%E5%9B%BE%E6%A1%86%E6%9E%B6Activity,Window,View,ViewRootImpl%E7%90%86%E8%A7%A3/)
### 一個下拉刷新界面的實現原理
### 什么是 ViewGroup ,它與 View 的區別在哪里?
### RecyclerView的復用原理
### RecyclerView緩存機制相比ListView緩存機制有啥改進
### 你知道什么是視圖樹(View Tree)嗎?怎樣優化它的深度?
### viewpager嵌套滑動沖突怎么解決
### 介紹一下svg動畫
[Android SVG矢量動畫機制](https://www.jianshu.com/p/47b0ae970dd5)
SVG動畫是在android5.X才引入(需要考慮兼容性問題)
## 動畫
### 補間動畫常見的效果?有哪幾個常見的插入器?
### 補間動畫click事件還在原位怎么解決?
## 布局
### android:gravity和android:layout_gravity的區別?
### 解釋layout_weight的作用
### android常用布局以及排版效率
### 約束布局的原理以及與相對布局之間的區別
### 布局怎么做到每行的文字左右對齊?
[不到100行代碼實現左右對齊TextView](https://www.jianshu.com/p/7241ed34346a)
## WebView相關
### 系統進程可以用webview嗎?
### WebView優化了解嗎,如何提高WebView的加載速度?
### Java和JS的相互調用怎么實現,有做過什么優化嗎?
## 編譯打包
### APK打包流程


Android打包流程總共七步:
(1)通過aapt打包res資源文件,生成R.java、resources.arsc和res文件(二進制 & 非二進制如res/raw和pic保持原樣)
(2)處理.aidl文件,生成對應的Java接口文件
(3)通過Java Compiler編譯R.java、Java接口文件、Java源文件,生成.class文件
(4)通過dex命令,將.class文件和第三方庫中的.class文件處理生成classes.dex
(5)通過apkbuilder工具,將aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk
(6)通過Jarsigner工具,對上面的apk進行debug或release簽名
(7)如果是正式版的APK,會利用ZipAlign工具進行對齊處理,對齊過程就是將APK文件中所有的資源文件距離文件的起始距離都偏移4字節的整數倍,這樣通過內存映射都偏移4字節的整數倍,這樣通過內存映射訪問APK文件速度會更快。

### 如何進行多渠道打包
### APK安裝流程
### 什么是 AAPT ?
### transform api
### 如何反編譯APP
## Android消息機制
### Android Handler機制是做什么的,原理了解嗎?

[你真應該再多了解些Handler機制](https://www.jianshu.com/p/8862bd2b6a29)
[Handler后傳篇一: 為什么Looper中的Loop()方法不能導致主線程卡死?](https://juejin.im/post/5c5694b951882562e5441e71?utm_source=gold_browser_extension)
### Android Binder機制是做什么的,為什么選用Binder,原理了解嗎?
* [為什么 Android 要采用 Binder 作為 IPC 機制?](https://www.zhihu.com/question/39440766)
### 介紹下 AIDL 的原理
## Android架構相關
### 什么是MVC
### 什么是MVP
### 什么是MVVM
### MVC、MVP以及MVVM的區別
### AAC架構
### ## 數據庫
### 常用開源數據庫框架介紹及實現原理
### 隔代數據庫升級
## 性能優化
### 性能優化的工具使用
### 內存優化(如何避免OOM)
[管理應用的內存](https://github.com/kesenhoo/android-training-course-in-chinese/blob/master/performance/memory.md)
[Android 內存管理機制](https://juejin.im/entry/589ff0d22f301e00694acbb3)
[Android內存管理](https://zhuanlan.zhihu.com/p/38025941)
### 渲染優化
#### 如何得到activity繪制完UI界面的時間
### 電量優化
### 體積優化
### ANR優化
## Bitmap相關
### Bitmap優化
[探索Bitmap使用姿勢](https://juejin.im/post/5c56bd57f265da2dc5388f33?utm_source=gold_browser_extension)
[Bitmap優化詳談](https://juejin.im/post/5bfbd5406fb9a049be5d2a20)
### 如何加載一張大圖
* Android如何在不壓縮的情況下加載高清大圖?
### Bitmap有幾種格式?一個像素分別占多少字節
* 如何計算一個Bitmap占用內存的大小,怎么保證加載Bitmap不產生內存溢出?
###
## 其他
### 如何理解嚴格模式(StrictMode)
嚴格模式是用來檢測程序中違例情況情況的開發者工具。最常用的場景就是檢查主線程中本地磁盤和網絡讀寫等耗時操作。使用嚴格模式,系統檢測出主線程違例的情況會做出相應的反應,如日志打印,彈出對話框亦或者崩潰等。換言之,嚴格模式會將應用的違例細節暴露給開發者方便優化與改善。
嚴格模式主要檢測兩大類問題,一個是線程策略即TreadPolicy,另一個是VM策略,即VmPolicy。
VmPolicy:
- Activity泄露 使用**detectActivityLeaks()**開啟
- 未關閉的Closable對象泄露 使用**detectLeakedClosableObjects()**開啟
- 泄露的Sqlite對象 使用**detectLeakedSqlLiteObjects()**開啟
- 檢測實例數量 使用**setClassInstanceLimit()**開啟
TreadPolicy:
- 自定義的耗時調用 使用**detectCustomSlowCalls()**開啟
- 磁盤讀取操作 使用**detectDiskReads()**開啟
- 磁盤寫入操作 使用**detectDiskWrites()**開啟
- 網絡操作 使用**detectNetwork()**開啟
[Android性能調優利器StrictMode](https://droidyue.com/blog/2015/09/26/android-tuning-tool-strictmode/)
### Android里的內存緩存和磁盤緩存是怎么實現的。
### SharePreference性能優化,可以做進程同步嗎?
### assets與res/raw的區別?
## Android多線程與多進程
### 解釋一下 AsyncTask及其原理
### AsyncTask 的生命周期和(它所屬的) Activity 的生命周期有什么關系?這種關系可能會導致什么樣的問題? 如何避免這些問題發生?
### 操作系統中進程與縣城有什么聯系和區別,系統什么時候回在用戶態和內核態中切換?
### Binder的原理?為什么要使用Binder?與Linux和Windows之間進程通訊的區別?
### ThreadLocal的原理
[ThreadLocal必知必會(基于JDK1.8)](https://mp.weixin.qq.com/s/AB4DF_b2t5lllmeuLH1GmQ)
## 其他
### 什么是9patch圖
[.9.png,全面認識“點九圖”](https://zhuanlan.zhihu.com/p/29217200)
> 點九圖是一種可拉伸的位圖,安卓會自動調整它的大小,來使圖像在充當背景時可以在界面中自適應。點九圖的一個典型使用場景,就是用作標準Android按鈕的背景圖,因為按鈕必須通過拉伸,來適應不同程度的字符。
點九圖是標準PNG格式的圖像,并且包含了多出來的1像素寬的邊界。保存點九圖時要以”.9.png”為結尾,放置在項目中“res/drawable/”的路徑之下。
四個黑邊代表什么含義?
* 上邊線:圖像橫向可拉伸的部分
* 左邊線:圖像縱向可拉伸的部分
* 右邊線:圖像縱向可填充內容(文字或圖片)區域
* 下邊線:圖像橫向可填充內容(文字或圖片)區域
### 什么是Context,Android有多少種Context
從Android系統的角度來理解:Context是一個場景,代表與操作系統的交互的一種過程。Context在加載資源、啟動Activity、獲取系統服務、創建View等操作都要參與 。從程序的角度上來理解:Context是個抽象類,而Activity、Service、Application等都是該類的一個實現。

### JSON有什么優劣勢、解析的原理以及與XML之間的對比
> JSON是一種輕量級的數據交換格式,具有良好的可讀和便于快速編寫的特性。業內主流技術為其提供了完整的解決方案(有點類似于正則表達式 ,獲得了當今大部分語言的支持),從而可以在不同平臺間進行數據交換。JSON采用兼容性很高的文本格式,同時也具備類似于C語言體系的行為。
**JSON 和 XML 優缺點的比較**
* 1.在可讀性方面,JSON和XML的數據可讀性基本相同。JSON和XML的可讀性可謂不相上下,一邊是建議的語法,一邊是規范的標簽形式,很難分出勝負。
* 2.在可擴展性方面,XML天生有很好的擴展性,JSON當然也有,沒有什么是XML能擴展,JSON不能的。
* 3.在編碼難度方面,XML有豐富的編碼工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的編碼明顯比XML容易許多,即使不借助工具也能寫出JSON的代碼,可是要寫好XML就不太容易了。
* 4.在解碼難度方面,XML的解析得考慮子節點父節點,讓人頭昏眼花,而JSON的解析難度幾乎為0。這一點XML輸的真是沒話說。
* 5.在流行度方面,XML已經被業界廣泛的使用,而JSON才剛剛開始,但是在Ajax這個特定的領域,未來的發展一定是XML讓位于JSON。到時Ajax應該變成Ajaj(Asynchronous JavaScript and JSON)了。
* 6.JSON和XML同樣擁有豐富的解析手段。
* 7.JSON相對于XML來講,數據的體積小。
* 8.JSON與JavaScript的交互更加方便。
* 9.JSON對數據的描述性比XML較差。
* 10.JSON的速度要遠遠快于XML。
### 理解序列化嗎,Android為什么引入Parcelable?
所謂序列化就是將對象變成二進制流,便于存儲和傳輸。
- Serializable是java實現的一套序列化方式,可能會觸發頻繁的IO操作,效率比較低,適合將對象存儲到磁盤上的情況。
- Parcelable是Android提供一套序列化機制,它將序列化后的字節流寫入到一個共性內存中,其他對象可以從這塊共享內存中讀出字節流,并反序列化成對象。因此效率比較高,適合在對象間或者進程間傳遞信息。
### 介紹Serializable和Parcelable的使用方法以及區別
* 1.實現Serializable接口需要添加serialVersionUID,不添加不會影響使用。UID在序列化的時候回寫入文件,反序列化的時候回讀取這個UID,并與反序列化中類的UID進行對比。如果相同則反序列化成功,不相同則反序列化失敗。當不指定UI的時候,系統會根據類的結構生成相應的hash賦值給UID,但是當類發生變化的時候UID就會發生變化,這樣會導致反序列化失敗。添加UID可以減少反序列化失敗的幾率。(但是當類發生了非常規的結構變化,如類名、成員變量類型變化,就算指定了UID,反序列化也會失敗)。
同時靜態類型變量不屬于對象,不會參與序列化過程;用transient關鍵字標記的成員變量不參與序列化過程。
* Parcelable接口各方法含義

**區別**
* 1.存儲媒介不同:Serializable使用 I/O 讀寫存儲在硬盤上,而Parcelable是直接在內存中讀寫。內存的讀寫速度通常大于I/O,所以在Android中傳遞數據有限使用Parcelable。
* 2.Serializable會使用反射,序列化和反序列化過程需要大量I/O操作,Parcelable自己實現封送和解封操作不需要使用反射,數據也存放在Native內存中,效率高很多。

###
### Lint靜態代碼檢查
參考Lint專欄
### 為什么 Bundle 被用來傳遞數據,為什么不能使用簡單的 Map 數據結構?
### 屏幕適配相關
* 修改系統density值系列
[騷年你的屏幕適配方式該升級了!-今日頭條適配方案](https://mp.weixin.qq.com/s/oSBUA7QKMWZURm1AHMyubA)
[一種極低成本的Android屏幕適配方式](https://mp.weixin.qq.com/s?__biz=MzI1MzYzMjE0MQ==&mid=2247484502&idx=2&sn=a60ea223de4171dd2022bc2c71e09351&scene=21#wechat_redirect)
總結:頭條修改density方案是通過實際屏幕寬度/高度(px單位)/ 設計圖寬度/高度(dp單位)重新計算出一個density值來進行適配。
* 限制適配符方案
[Android 目前穩定高效的UI適配方案](https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650826034&idx=1&sn=5e86768d7abc1850b057941cdd003927&chksm=80b7b1acb7c038ba8912b9a09f7e0d41eef13ec0cea19462e47c4e4fe6a08ab760fec864c777&scene=21#wechat_redirect)
[騷年你的屏幕適配方式該升級了!-smallestWidth 限定符適配方案](https://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650826381&idx=1&sn=5b71b7f1654b04a55fca25b0e90a4433&chksm=80b7b213b7c03b0598f6014bfa2f7de12e1f32ca9f7b7fc49a2cf0f96440e4a7897d45c788fb&scene=21#wechat_redirect)
### app閃退的原因有哪些?每種情況簡述一下分析過程
### 解析xml有哪幾種方式,優缺點分別是什么?
### 自己寫一個應用,包名就叫android行不行,為什么?
## Android系統新特性
### 權限管理
## Android虛擬機相關
### 字節碼
[一起玩轉Android項目中的字節碼](http://quinnchen.me/2018/09/13/2018-09-13-asm-transform/)
### 什么是 Dalvik 虛擬機?
參考:[簡單理解Android Dalvik、ART及APK編譯過程](https://www.jianshu.com/p/92227738f270)
Dalvik是Google公司自己設計用于Android平臺的Java虛擬機,它是Android平臺的重要組成部分,支持dex格式(Dalvik Executable)的Java應用程序的運行。dex格式是專門為Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統。Google對其進行了特定的優化,使得Dalvik具有高效、簡潔、節省資源的特點。從Android系統架構圖知,Dalvik虛擬機運行在Android的運行時庫層。
Dalvik作為面向Linux、為嵌入式操作系統設計的虛擬機,主要負責完成對象生命周期管理、堆棧管理、線程管理、安全和異常管理,以及垃圾回收等。另外,Dalvik早期并沒有JIT編譯器,直到Android2.2才加入了對JIT的技術支持。
### Dalvik虛擬機的特點
* 體積小,占用內存空間小;
* 專有的DEX可執行文件格式,體積更小,執行速度更快;
* 常量池采用32位索引值,尋址類方法名,字段名,常量更快;
* 基于寄存器架構,并擁有一套完整的指令系統;
* 提供了對象生命周期管理,堆棧管理,線程管理,安全和異常管理以及垃圾回收等重要功能;
* 所有的Android程序都運行在Android系統進程里,每個進程對應著一個Dalvik虛擬機實例。
### Dalvik虛擬機與Java虛擬機的區別
* Java虛擬機運行的是Java字節碼,Dalvik虛擬機運行的是Dalvik字節碼
傳統的Java程序經過編譯,生成Java字節碼保存在class文件中,Java虛擬機通過解碼class文件中的內容來運行程序。而Dalvik虛擬機運行的是Dalvik字節碼,所有的Dalvik字節碼由Java字節碼轉換而來,并被打包到一個DEX(Dalvik Executable)可執行文件中。Dalvik虛擬機通過解釋DEX文件來執行這些字節碼。

* Dalvik可執行文件體積小。Android SDK中有一個叫dx的工具負責將Java字節碼轉換為Dalvik字節碼
dx工具對Java類文件重新排列,消除在類文件中出現的所有冗余信息,避免虛擬機在初始化時出現反復的文件加載與解析過程。一般情況下,Java類文件中包含多個不同的方法簽名,如果其他的類文件引用該類文件中的方法,方法簽名也會被復制到其類文件中,也就是說,多個不同的類會同時包含相同的方法簽名,同樣地,大量的字符串常量在多個類文件中也被重復使用。這些冗余信息會直接增加文件的體積,同時也會嚴重影響虛擬機解析文件的效率。消除其中的冗余信息,重新組合形成一個常量池,所有的類文件共享同一個常量池。由于dx工具對常量池的壓縮,使得相同的字符串,常量在DEX文件中只出現一次,從而減小了文件的體積。
針對每個Class文件,都由如下格式進行組成:

dex格式文件使用共享的、特定類型的常量池機制來節省內存。常量池存儲類中的所有字面常量,它包括字符串常量、字段常量等值。總的來說,dex格式文件就是將多個class文件中公有的部分統一存放,去除冗余信息。

* Java虛擬機與Dalvik虛擬機架構不同。這也是Dalvik與JVM之間最大的區別。**Java虛擬機基于棧架構**,程序在運行時虛擬機需要頻繁的從棧上讀取或寫入數據,這個過程需要更多的指令分派與內存訪問次數,會耗費不少CPU時間,對于像手機設備資源有限的設備來說,這是相當大的一筆開銷。**Dalvik虛擬機基于寄存器架構**。數據的訪問通過寄存器間直接傳遞,這樣的訪問方式比基于棧方式要快很多。
### Dalvik虛擬機結構

一個應用首先經過DX工具將class文件轉換成Dalvik虛擬機可以執行的dex文件,然后由類加載器加載原生類和Java類,接著由解釋器根據指令集對Dalvik字節碼進行解釋、執行。最后,根據dvm_arch參數選擇編譯的目標機體系結構。
### 什么是ART
ART代表Android Runtime,其處理應用程序執行的方式完全不同于Dalvik,Dalvik是依靠一個Just-In-Time (JIT)編譯器去解釋字節碼。開發者編譯后的應用代碼需要通過一個解釋器在用戶的設備上運行,這一機制并不高效,但讓應用能更容易在不同硬件和架構上運 行。ART則完全改變了這套做法,在應用安裝時就預編譯字節碼到機器語言,這一機制叫Ahead-Of-Time (AOT)編譯。在移除解釋代碼這一過程后,應用程序執行將更有效率,啟動更快。
* 優點:
* 系統性能的顯著提升。
* 應用啟動更快、運行更快、體驗更流暢、觸感反饋更及時。
* 更長的電池續航能力。
* 支持更低的硬件。
* 缺點:
* 更大的存儲空間占用,可能會增加10%-20%。
* 更長的應用安裝時間
### Dalvik 虛擬機模式和 ART(Android Runtime)虛擬機模式的區別
[ART 和 Dalvik](https://source.android.com/devices/tech/dalvik)
[Android GC機制實踐調研](https://lizhaoxuan.github.io/2016/02/17/androidgcdiaoyan/)
* Dalvik虛擬機是在4.4以及以下系統使用,ART虛擬機在Android4.4以上使用
* Dalvik采用JIT(Just In Time Compiler)技術,ART使用AOT(Ahead Of Time)技術
* 垃圾回收方面的區別:
* dalvik gc總共有四個過程
* 1.當gc被觸發時候,其會去查找所有活動的對象,這個時候整個程序與虛擬機內部的所有線程就會掛起,這樣目的是在較少的堆棧里找到所引用的對象.需要注意的是這個回收動作是和應用程序**同時執行(非并發)**.
* 2.gc對符合條件的對象進行標記
* 3.gc對標記的對象進行回收
* 4.恢復所有線程的執行現場繼續運行

dalvik這么做的好處是,當pause之后,gc勢必是相當快速的,但是如果出現gc頻繁并且內存赤金勢必會導致UI卡頓,掉幀、操作不流暢等。art改善了這種gc方式,主要的改善點在其非并發過程改變成了部分并發,還有就是對內存的重新分配管理。
dalvik采用的標記-清除(Mark and Sweep)算法會導致內存碎片化特別嚴重,每次gc后內存千瘡百孔,本來連續的內存塊變得碎片化特別嚴重,之后再進入的對象再進行內存尋址變得十分困難。
當art gc發生時:
* 1.gc將會鎖住java堆,掃描并進行標記
* 2.標記完畢釋放掉java堆的鎖,并且掛起所有線程
* 3.gc對標記的對象進行回收
* 4.恢復所有線程的執行現場繼續運行
* 5.重復2-4直到結束
可以看出整個過程做到了部分并發使得時間縮短.據官方測試數據說gc效率提高2倍
內存碎片問題上,在art中,它將java分了一塊空間命名為**Large-Object-Space**,這塊內存空間的引入用來專門存放large object.同時art又引入了moving collector的技術,即將不連續的物理內存塊進行對齊.對齊了后內存碎片化就得到了很好的解決.Large-Object-Space的引入一是因為moving collector對大塊內存的位移時間成本太高,而且提高內存的利用率。
[Dalvik虛擬機和ART(Android RunTime)的區別](https://blog.csdn.net/lixpjita39/article/details/73058020)
### Android類加載機制流程
[Android虛擬機框架:類加載機制](https://juejin.im/post/5a686596f265da3e2d339bb4)
[Android類加載器ClassLoader](http://gityuan.com/2017/03/19/android-classloader/)
### PathClassLoader與DexClassLoader有什么區別?
* PathClassLoader: 主要用于系統和app的類加載器,其中optimizedDirectory為null, 采用默認目錄/data/dalvik-cache/
* DexClassLoader: 可以從包含classes.dex的jar或者apk中,加載類的類加載器, 可用于執行動態加載, 但必須是app私有可寫目錄來緩存odex文件. 能夠加載系統沒有安裝的apk或者jar文件,因此很多插件化方案都是采用DexClassLoader;
### 描述一下類加載機制以及其原理在熱修復當中的應用
## Android經典代碼分析
### layoutinflater分析
[LayoutInflater源碼分析](https://bboylin.github.io/2018/12/21/LayoutInflater%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/)
### ArrayMap分析
## NDK相關
### 如何加載ndk庫?如何在jni中注冊native函數,有幾種注冊方式?
### 在android中,請簡述jni的調用過程
- 計算機基礎
- 簡答1
- 簡答2
- 專案
- 淺談0與1
- 淺談TCP_IP
- 淺談HTTP
- 淺談HTTPS
- 數據結構與算法
- 常見數據結構簡介
- 常用算法分析
- 常見排序算法
- Java數據結構類問題簡答
- 專案
- HashMap
- 淺談二叉樹
- 算法題
- 算法001_TopN問題
- 算法002_漢諾塔
- 編程思想
- 雜說
- 觀點_優秀程序設計的18大原則
- 設計模式_創建型
- 1_
- 2_
- 設計模式_結構型
- 1_
- 2_
- 設計模式_行為型
- 1_
- 2_
- Java相關
- 簡答1
- 簡答2
- 專案
- 淺談String
- 淺談Java泛型
- 淺談Java異常
- 淺談動態代理
- 淺談AOP編程
- 淺談ThreadLocal
- 淺談Volatile
- 淺談內存模型
- 淺談類加載
- 專案_數據結構
- 淺談SpareArray
- Android相關
- Android面試題
- 專案
- 推送原理解析
- Lint
- 自定義Lint
- Lint使用
- 優化案
- Apk體積優化
- Kotlin相關
- 簡答1
- 簡答2
- 三方框架相
- Okhttp3源碼分析
- ButterKnife源碼分析
- Glide4源碼分析
- Retrofit源碼分析
- RxJava源碼分析
- ARouter源碼分析
- LeakCanary源碼分析
- WMRouter源碼分析
- 跨平臺相關
- ReactNative
- Flutter
- Hybrid
- 優質源
- 資訊源
- 組件源
- 推薦