Android高級崗面試刷題02

1.MVC,MVP架構的區別。

https://www.jianshu.com/p/78e0a508b1c6

結合自己項目使用的MVP談談感想。

2.如何解決Handler導致的內存泄漏。

在java中非靜態內部類和匿名內部類都會隱式持有當前類的外部引用,由於Handler是非靜態內部類所以其持有當前Activity的隱式引用,如果Handler沒有被釋放,其所持有的外部引用也就是Activity也不可能被釋放,當一個對象不需要再使用了,本來該被回收時,而有另外一個正在使用的對象持有它的引用從而導致它不能被回收,這導致本該被回收的對象不能被回收而停留在堆內存中,這就產生了內存泄漏。最終也就造成了OOM.......

解決辦法:設置爲靜態內部類,並且持有Activity的弱引用。

3.LruCache算法的原理。

LRULeast Recently Used的縮寫,意思也就是近期最少使用算法。LruCacheLinkedHashMap的順序設置爲LRU順序來實現LRU緩存,每次調用get並獲取到值(也就是從內存緩存中命中),則將該對象移到鏈表的尾端。調用put插入新的對象也是存儲在鏈表尾端,這樣當內存緩存達到設定的最大值時,將鏈表頭部的對象(近期最少用到的)移除。

4.簡述View的繪製流程。(非常重要,面試必說,不問自己也要說!)

https://www.cnblogs.com/mingfeng002/p/9143831.html

https://baijiahao.baidu.com/s?id=1652990190210449929&wfr=spider&for=pc

mWindow = new PhoneWindow(this);

mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),

mToken, mComponent.flattenToString(),

WindowManageraddView的過程,WindowManager是個接口,它的實現類是WindowManagerImpl類,而WindowManagerImpl又把相關邏輯交給了WindowManagerGlobal處理。WindowManagerGlobal是個單例類,它在進程中只存在一個實例,是它內部的addView方法最終創建了我們的核心類ViewRootImpl

可以看到這裏的WindowManagerImpl 的主要功能都是通過WindowManagerGlobal來實現的

ViewRootImpl之中的requestLayout()

performTraversals()!而它裏的實現就是調用咱們熟悉的performLayout()、performMeasure()、performDraw()的地方了~

1、mesarue()過程
主要作用:爲整個 View 樹計算實際的大小,即設置實際的高(對應屬性:mMeasuredHeight)和寬(對應屬性:
mMeasureWidth),每個 View 的控件的實際寬高都是由父視圖和本身視圖決定的。
具體的調用鏈如下: ViewRoot 根對象的屬性 mView(其類型一般爲 ViewGroup 類型)調用 measure()方法去
計算 View 樹的大小,回調 View/ViewGroup 對象的 onMeasure()方法,該方法實現的功能如下:
1、設置本 View 視圖的最終大小,該功能的實現通過調用 setMeasuredDimension()方法去設置實際
的高(對應屬性:mMeasuredHeight)和寬(對應屬性:mMeasureWidth)。
2 、如果該 View 對象是個 ViewGroup 類型,需要重寫該 onMeasure()方法,對其子視圖進行遍歷的
measure() 過 程 。 對 每 個 子 視 圖 的 measure() 過 程 , 是 通 過 調 用 父 類 ViewGroup.java 類 裏 的
measureChildWithMargins()方法去實現,該方法內部只是簡單地調用了 View 對象的 measure()方法。
2、layout 佈局過程
主要作用:爲將整個根據子視圖的大小以及佈局參數將 View 樹放到合適的位置上。
具體的調用鏈如下:
1、layout 方法會設置該 View 視圖位於父視圖的座標軸,即 mLeft,mTop,mLeft,mBottom(調用
setFrame()函數去實現)接下來回調 onLayout()方法(如果該 View 是 ViewGroup 對象,需要實現該方法,對每個子視
圖進行佈局)。
2、如果該 View 是個 ViewGroup 類型,需要遍歷每個子視圖 chiildView,調用該子視圖的 layout()方法
去設置它的座標值。
3、draw()繪圖過程
由 ViewRoot 對象的 performTraversals()方法調用 draw()方法發起繪製該 View 樹,值得注意的是每次發起繪
圖時,並不會重新繪製每個 View 樹的視圖,而只會重新繪製那些“需要重繪”的視圖,View 類內部變量包含了一個
標誌位 DRAWN,當該視圖需要重繪時,就會爲該 View 添加該標誌位。
調用流程 :
1 、繪製該 View 的背景
2 、爲顯示漸變框做一些準備操作(大多數情況下,不需要改漸變框)
3、調用 onDraw()方法繪製視圖本身(每個 View 都需要重載該方法,ViewGroup 不需要實現該方法)
4、調用 dispatchDraw ()方法繪製子視圖(如果該 View 類型不爲 ViewGroup,即不包含子視圖,不
需要重載該方法)
值得說明的是,ViewGroup 類已經爲我們重寫了 dispatchDraw ()的功能實現,應用程序一般不需要重寫該方法,
但可以重載父類函數實現具體的功能。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章