設(shè)計模式:http://www.reibang.com/p/35f76e87ac45
java基礎(chǔ):https://xiaozhuanlan.com/topic/7548023169
jvm:
創(chuàng)建對象:https://blog.csdn.net/xiha_zhu/article/details/83614985
jvm面試:https://blog.csdn.net/HarderXin/article/details/104066411
GC回收:https://juejin.cn/post/6844903889850875917#heading-14
-
可達性分析算法
GC Root開始往下搜索黄刚,搜索所走過的對象稱為引用鏈,如果一個對象到GCroot沒有一個對象關(guān)聯(lián)景埃,則這個對象會被GC回收
GC Root:不會被GC管理的對象粱年,方法區(qū)、棧项贺、本地方法區(qū)不會進行GC回收
GCRoot:
(JVM棧(棧幀數(shù)據(jù)中的本地變量表)中引用的對象岁诉。方法區(qū)中類靜態(tài)屬性引用的對象纬乍。
方法區(qū)中常量引用的對象。Native 方法棧中JNI引用的對象)锁孟。
HashMap:https://cloud.tencent.com/developer/article/1629452
面試題:https://my.oschina.net/u/4584159/blog/4374322
面試題(2的冪)https://www.cnblogs.com/java1024/p/13488714.html
==彬祖、hashcode聯(lián)系:http://www.reibang.com/p/c7c0828c1de6
String、StringBuffer區(qū)別:http://www.reibang.com/p/2c9a23c8ff0c
http,https/tcp,udp:http://www.reibang.com/p/e974e6dfa293
https://cloud.tencent.com/developer/article/1572109
線程及進程罗岖,安卓中多進程的使用及優(yōu)劣勢分析
java線程池:https://blog.csdn.net/evilcry2012/article/details/79657477
安卓多線程:https://cloud.tencent.com/developer/article/1446299
安卓多進程:
https://chchaooo.github.io/2019/01/19/Android%E5%A4%9A%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1/
java理解
反射:https://blog.csdn.net/weixin_43647393/article/details/103301969
注解:http://www.reibang.com/p/d263fd7aaf96
hook:
整個Hook過程簡要總結(jié)如下:
尋找Hook點涧至,原則是靜態(tài)變量或者單例對象,盡量Hook pulic的對象和方法桑包,非public不保證>>每個版本都一樣南蓬,需要適配。
選擇合適的代理方式
如果是接口可以用動態(tài)代理哑了; 因為動態(tài)代理只用于接口編程
如果是類可以手動寫代理赘方,或者直接繼承重寫函數(shù),也可以使用cglib
偷梁換柱——用代理對象替換原始對象弱左,往往使用反射***
代理
靜態(tài)代理:編譯時期就已經(jīng)存在窄陡,一般首先需要定義接口,而被代理的對象和代理對象一起實現(xiàn)相同的接口拆火。
動態(tài)代理:動態(tài)代理可以在運行時動態(tài)創(chuàng)建一個類跳夭,實現(xiàn)一個或多個接口,可以在不修改原有類的基礎(chǔ)上動態(tài)為通過該類獲取的對象添加方法们镜、修改行為币叹。
https://blog.csdn.net/mcryeasy/article/details/83689396?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=1328665.7062.16159520679702053&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
Binder序列化:https://blog.csdn.net/weixin_47933729/article/details/112349766?spm=1001.2014.3001.5501
面試題:接口和抽象類的區(qū)別?
接口(interface)和抽象類(abstract class)是支持抽象類定義的兩種機制。
接口是公開的模狭,不能有私有的方法或變量颈抚,接口中的所有方法都沒有方法體,通過關(guān)鍵字interface實現(xiàn)嚼鹉。
抽象類是可以有私有方法或私有變量的贩汉,通過把類或者類中的方法聲明為abstract來表示一個類是抽象類驱富,被聲明為抽象的方法不能包含方法體。子類實現(xiàn)方法必須含有相同的或者更低的訪問級別(public->protected->private)匹舞。抽象類的子類為父類中所有抽象方法的具體實現(xiàn)褐鸥,否則也是抽象類。
接口可以被看作是抽象類的變體策菜,接口中所有的方法都是抽象的晶疼,可以通過接口來間接的實現(xiàn)多重繼承。接口中的成員變量都是static final類型又憨,由于抽象類可以包含部分方法的實現(xiàn)翠霍,所以,在一些場合下抽象類比接口更有優(yōu)勢蠢莺。
相同點:(1)都不能被實例化 (2)接口的實現(xiàn)類或抽象類的子類都只有實現(xiàn)了接口或抽象類中的方法后才能實例化寒匙。
不同點:
- (1)接口只有定義,不能有方法的實現(xiàn)躏将,java 1.8中可以定義default方法體锄弱,而抽象類可以有定義與實現(xiàn),方法可在抽象類中實現(xiàn)祸憋。
- (2)實現(xiàn)接口的關(guān)鍵字為implements会宪,繼承抽象類的關(guān)鍵字為extends。一個類可以實現(xiàn)多個接口蚯窥,但一個類只能繼承一個抽象類掸鹅。所以,使用接口可以間接地實現(xiàn)多重繼承拦赠。
- (3)接口強調(diào)特定功能的實現(xiàn)巍沙,而抽象類強調(diào)所屬關(guān)系。
- (4)接口成員變量默認為public static final荷鼠,必須賦初值句携,不能被修改;其所有的成員方法都是public允乐、abstract的矮嫉。抽象類中成員變量默認default,可在子類中被重新定義牍疏,也可被重新賦值蠢笋;抽象方法被abstract修飾,不能被private麸澜、static、synchronized和native等修飾奏黑,必須以分號結(jié)尾炊邦,不帶花括號编矾。
- (5)接口被用于常用的功能,便于日后維護和添加刪除馁害,而抽象類更傾向于充當公共類的角色窄俏,不適用于日后重新對立面的代碼修改。功能需要累積時用抽象類碘菜,不需要累積時用接口凹蜈。
----------------------------- Android -----------------------------------
安卓源碼解析:https://www.kancloud.cn/digest/androidframeworks/127779
activity和fragment:https://cloud.tencent.com/developer/article/1618374
書籍翻頁效果: http://www.reibang.com/p/d02362fbd9f2
ANR及Crash:https://juejin.cn/post/6844903972587716621#heading-5
Native crash:https://cloud.tencent.com/developer/article/1192001
Android優(yōu)化:
應(yīng)用啟動優(yōu)化:https://androidperformance.com/2019/11/18/Android-App-Lunch-Optimize/#App-%E4%BC%98%E5%8C%96
內(nèi)存優(yōu)化:https://blog.csdn.net/carson_ho/article/details/79549417
動態(tài)化方案:
簡介:https://tech.meituan.com/2019/09/19/litho-practice-in-dynamic-program-mtflexbox.html
Litho:https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651750430&idx=2&sn=89c8c1212f4b6a24694028ec3188aa09&from=timeline
Android設(shè)計模式:
各模式簡介:https://www.kancloud.cn/s1657292627/android_ios/622850
MVP+Clean:MVP 之 View 和 Presenter 層作為 Clean 架構(gòu)的 Presentations Layer, 新增 Domain Layer 處理所有的業(yè)務(wù)邏輯。MVP 中的 Model 層功能被弱化忍啸,作為 Data Layer 對外只提供接口仰坦,不再有業(yè)務(wù)邏輯。 一般來說每一層都有獨立的數(shù)據(jù)模型
https://blog.csdn.net/Kennethdroid/article/details/90178944?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-13&spm=1001.2101.3001.4242
Android消息機制
一個線程一個Loop计雌,怎么保證悄晃?
Thread里存在一個變量threadLocals —> threadLocals=new ThreadLocalMap —>>ThreadLocalMap里面存的是Entry<key,value>,key存的是ThreadLocal,value即Loop
Loop.prepare()方法中凿滤,mThreadLocal.get()!=null—>拋出異常妈橄。
Handler面試:
面試題(IdleHandler):https://zhuanlan.zhihu.com/p/356439052
進階:https://blog.csdn.net/xk7298/article/details/104157542
虛擬機:http://www.reibang.com/p/4bc97c554884
安卓插件化:https://juejin.cn/post/6844903965679681549#heading-20
dex分包:http://yunlaiwu.github.io/blog/2016/06/15/Dex/
安卓打包編譯流程:
- aapt將資源文件打包生成R.java及Resource.arsc
- aidl工具將aidl文件編譯成.java文件
- R.java加工程源碼加aidl.java通過javac編譯生成.class文件
- 源碼.class文件和第三方j(luò)ar或者library通過dx工具打包成dex文件(對 .class 文件進行翻譯、重構(gòu)翁脆、解釋眷蚓、壓縮)
dexopt對dex文件進行Verification和optimization的操作,其對dex文件的優(yōu)化結(jié)果變成了odex文件反番,優(yōu)化內(nèi)容:
a.對于虛方法的調(diào)用沙热,把方法索引修改成vtable索引
b. 把field的get/put修改成字節(jié)偏移量。把boolean/byte/char/short等類型的變量
c. 把一些大量使用的簡單方法進行inline恬口,減少方法調(diào)用的開銷
d. 刪除空方法
e.加入一些計算好的數(shù)據(jù)校读。比如,VM需要一個hash table來查找類名字祖能。- apkbuilder工具會將所有沒有編譯的資源歉秫、.arsc資源、.dex文件打包到一個完成apk文件中
- jarsigner工具會對未簽名的apk驗證簽名养铸。得到一個簽名后的apk(signed.apk)
- zipAlign工具對6中的signed.apk進行對齊處理
網(wǎng)絡(luò)請求:
okhttp:https://blog.csdn.net/u012881042/article/details/79759203
retofit: https://juejin.cn/post/6844903799350362119
網(wǎng)絡(luò)優(yōu)化: https://zhuanlan.zhihu.com/p/162429374
Glide:https://juejin.cn/post/6844903986412126216#heading-2
性能優(yōu)化:https://blog.csdn.net/carson_ho/article/details/79549417
----------------------------- 自己梳理 -----------------------------------
一. App/Activity啟動流程
1. 系統(tǒng)啟動流程
系統(tǒng)啟動:BootLoader拉起linux內(nèi)核->加載驅(qū)動->加載系統(tǒng)OS->init進程開啟(init.rc腳本)->zygote進程(作用:孵化進程)->System server進程
zygote進程啟動:
init()進程啟動完成->解析init.zygote.rc腳本->創(chuàng)建zygote進程->app_main.cpp main()
System server進程(80多個服務(wù))
app_main.cpp main()->安卓運行時環(huán)境雁芙、啟動虛擬機->registerZygoteSocket->開啟system server進程->開啟loop-
AMS啟動:
system server進程的main()->run()->startBootStrapService()、startCoreService()钞螟、startOtherService()startBootStrapService()中啟動AMS
SystemServiceManager: AMS PMS......
service_manager:管理binder服務(wù)
startBootStrapService:
2. startActivity啟動流程
跨進程: https://www.cnblogs.com/andy-songwei/p/10256379.html
- 跨進程通信Binder IPC
Binder:https://blog.csdn.net/AndroidStudyDay/article/details/93749470
- 性能:mmap()內(nèi)存映射,copy一次數(shù)據(jù)兔甘,而socket、管道都是兩次鳞滨;共享內(nèi)存一次不需要洞焙。
- 穩(wěn)定性:Binder采用C/S架構(gòu)
- 安全:Linux IPC接收方無法得得到對方進程可靠的UID/PID,無法鑒別對方身份,完全由上層協(xié)議確保
AIDL以及序列化:https://blog.csdn.net/weixin_47933729/article/details/112349766?spm=1001.2014.3001.5501
- activity啟動流程
instrumentation.execStartActivity->Binder b=ServiceManager.getService()獲取到binder服務(wù)、IActivityManager.stub.asInterface(b)得到AMS的代理類->AMS.startActivity
AMS.startActivity()->AMS.startActivityAsUser(IApplicationThread caller...):caller用于AMS給app回傳
——>ActivityStarter.startActivityMyWait():獲取啟動意圖及啟動Activity信息澡匪。
——>ActivityStarter.startActivityUnchecked()
——>ActivityStackSupervisor.resumeTopActivityLocked
——>ActivityStackSupervisor.startSpecificActivityLocked()
ProcessRecord...判斷應(yīng)用進程是否存在熔任,不存在,請求zygote fork應(yīng)用進程唁情。startProcessLocked疑苔,請求zygote fork應(yīng)用進程。
存在甸鸟,ActivityThread.main(),loop循環(huán)惦费,attach,然后IActivityManager.attachApplication, 到AMS.
——>ActivityStackSupervisor.realStartActivityLocked()app.thread.scheduleLaunchActivity(IApplicatiponThread) ,他的實現(xiàn)類是ApplicationThread->ApplicationThread.scheduleLaunchActivity->Handler中處理handleLaunchActivity->performLaunchActivity
performLaunchActivity的主要流程:
- 從ActivityClientRecord中獲取待啟動Activity的組件信息抢韭。
- 通過Instrumentation的newActivity方法使用類加載器去創(chuàng)建Activity對象薪贫。
- 通過LoadApk的makeApplication方法來嘗試創(chuàng)建Application對象。
- 創(chuàng)建ComtextImpl對象并通過Activity的attach方法來完成一些重要數(shù)據(jù)的初始化篮绰。
- 調(diào)用Activity的onCreate方法
3. AMS中的代理模式
ActivityManager的代理模式: https://www.cnblogs.com/mingfeng002/p/10650364.html
三.View繪制及View分發(fā)
window相關(guān):https://cloud.tencent.com/developer/article/1601350
view繪制:
簡述:
一個 Activity 包含一個Window后雷,Window是一個抽象基類,是 Activity 和整個 View 系統(tǒng)交互的接口吠各,只有一個實現(xiàn)子類PhoneWindow臀突,提供了一系列窗口的方法,比如設(shè)置背景贾漏,標題等候学。一個PhoneWindow 對應(yīng)一個DecorView 跟 一個 ViewRootImpl,DecorView 是ViewTree 里面的頂層布局纵散,是繼承于FrameLayout梳码,包含兩個子View,一個id=statusBarBackground 的 View 和 LineaLayout伍掀,LineaLayout 里面包含 title 跟content掰茶,title就是平時用的TitleBar或者ActionBar, content也是FrameLayout蜜笤,activity通過 setContent()加載布局的時候加載到這個View上濒蒋。ViewRootImpl就是建立 DecorView 和 Window 之間的聯(lián)系
viewRootImpl繪制流程詳解
ViewRoot對應(yīng)ViewRootImpl類,它是連接WMS和DecorView的紐帶把兔,但它卻并不屬于View樹的一份子沪伙,并不是View的子類也不是View的父類,但它實現(xiàn)了ViewParent接口县好,所以可以作為名義上的View的父視圖围橡。
WindowManager.addView()內(nèi)部實際是由WindowManagerGlobal完成的,WindowManagerGlobal中有三個列表缕贡,一個是保存View的mViews列表翁授,一個是保存ViewRootImpl的mRoots列表拣播,一個是保存WindowManager.LayoutParams的mParams列表,WindowManager每一次addView()都會創(chuàng)建一個對應(yīng)的ViewRootImpl收擦,在調(diào)用ViewRoot.setView后將decorView交給ViewRootImpl诫尽。ViewRootImpl中調(diào)用performTraversals方法,然后便開始測量布局繪畫了炬守,界面才得以顯示出來,這就是View的繪制流程起點剂跟。
- viewRootImpl會調(diào)用performTraversals()减途,其內(nèi)部會調(diào)用performMeasure(),performLayout,performDraw() 方法
- performMeasure()會調(diào)用最外層的ViewGroup的measure()--->onMeasure() ---->ViewGroup的onMeasure() 方法是抽象方法曹洽,但其提供了measeureChilden()方法鳍置,這個會遍歷子View 然后循環(huán)調(diào)用measureChilden() ,這個方法中會調(diào)用getChildMeasureSpec() + 父View的MeasureSpec + 子View的LayoutParam 一起獲取到本身View的MeasueSpec,然后調(diào)用子View的measure()到view的onMeasure()--->setMeasuredDimension(getDefaultSize(),getDefaultSize()) 默認返回measureSpec的測量數(shù)值 送淆,所以繼承View 進行自定義的wrap_content 需要重寫
- performLayout() 會調(diào)用最外層的ViewGroup的layou(l,t,r,b) ,本身View在其中使用setFrame(),設(shè)置本View的四個頂點位置税产,在onLayout(抽象方法)中確定子View的位置 ,比如LinearLayout 會遍歷子View ,循環(huán)調(diào)用 setChildFrame--->子View的layout方法
- performDraw()會調(diào)用最外層的ViewGroup的draw(),其中會先后調(diào)用background.draw () 繪制背景偷崩,onDraw 方法 繪制自己本身View ---> 調(diào)用dispatchDraw() 進行子View 繪制---->onDrawScrollBars() 繪制裝飾
- MeasureSpec 由2位SpecMode(UNSPECIFIED,EXACTILY(對應(yīng)精確值和match_parent),AT_MOST 對應(yīng)warp_content) 和30位SpecSize 組成一個int辟拷,DecorView的MeasureSpec 是由窗口大小與其LayoutParams決定,其他View 是由父View的MeasureSpec 和本身的View的layoutParams 來決定 阐斜,ViewGroup 中有g(shù)etChildenMeasureSpec() 來獲取子View 的measureSpec
EXACTLY:父容器已經(jīng)測量出子View的大小衫冻。對應(yīng)是 View 的LayoutParams的match_parent 或者精確數(shù)值。
AT_MOST:父容器已經(jīng)限制子view的大小谒出,View 最終大小不可超過這個值隅俘。對應(yīng)是 View 的LayoutParams的wrap_content
UNSPECIFIED:父容器不對View有任何限制,要多大給多大笤喳,這種情況一般用于系統(tǒng)內(nèi)部为居,表示一種測量的狀態(tài)。 - 三種方式獲取measure()后的寬高值
a.activity中的onWindowFocusChange() 方法中調(diào)用獲取
b.view.post(Runnable) 將在run方法中進行獲取
c.view.setViewTreeObserbable 監(jiān)聽中進行獲取
draw流程
- draw
- drawBackground(canvas): 作用就是繪制 View 的背景杀狡。
- onDraw(canvas) :繪制 View 的內(nèi)容蒙畴。View 的內(nèi)容是根據(jù)自己需求自己繪制的,所以方法是一個空方法捣卤,View的繼承類自己復(fù)寫實現(xiàn)繪制內(nèi)容忍抽。
- dispatchDraw(canvas):遍歷子View進行繪制內(nèi)容。在 View 里面是一個空實現(xiàn)董朝,ViewGroup 里面才會有實現(xiàn)鸠项。在自定義 ViewGroup 一般不用復(fù)寫這個方法,因為它在里面的實現(xiàn)幫我們實現(xiàn)了子 View 的繪制過程子姜,基本滿足需求祟绊。
- onDrawForeground(canvas):對前景色跟滾動條進行繪制楼入。
- drawDefaultFocusHighlight(canvas):繪制默認焦點高亮
View事件分發(fā)機制:
原理:http://www.reibang.com/p/e99b5e8bd67b
面試題:https://segmentfault.com/a/1190000039254459
RecycleView緩存: https://www.cnblogs.com/jimuzz/p/14040674.html
view繪制及recyclerView相關(guān): https://blog.csdn.net/harvic880925/article/details/50995268
算法:
二分查找: https://blog.csdn.net/maoyuanming0806/article/details/78176957