【Android】佈局

Window、DecorView、ViewRootImpl

20190103210016632.png
1.點擊桌面APP圖標時,Launcher的startActivity()方法,經過Binder通訊,調用system_server進程中AMS服務的startActivity方法,發起啓動請求
3.2.system_server進程接收到請求後,向Zygote進程發送建立進程的請求
Zygote進程fork出App進程,並執行ActivityThread的main方法,建立ActivityThread線程,初始化MainLooper,主線程Handler,同時初始化ApplicationThread用於和AMS通訊交互
4.App進程,經過Binder向sytem_server進程發起attachApplication請求,這裏實際上就是APP進程經過Binder調用sytem_server進程中AMS的attachApplication方法,上面咱們已經分析過,AMS的attachApplication方法的做用是將ApplicationThread對象與AMS綁定
5.system_server進程在收到attachApplication的請求,進行一些準備工做後,再經過binder IPC向App進程發送handleBindApplication請求(初始化Application並調用onCreate方法)和scheduleLaunchActivity請求(建立啓動Activity)
6.App進程的binder線程(ApplicationThread)在收到請求後,經過handler向主線程發送BIND_APPLICATION和LAUNCH_ACTIVITY消息,這裏注意的是AMS和主線程並不直接通訊,而是AMS和主線程的內部類6.ApplicationThread經過Binder通訊,ApplicationThread再和主線程經過Handler消息交互。 ( 這裏猜想這樣的設計意圖多是爲了統一管理主線程與AMS的通訊,而且不向AMS暴露主線程中的其餘公開方法,大神能夠來解析下)
7.主線程在收到Message後,建立Application並調用onCreate方法,再經過反射機制建立目標Activity,並回調Activity.onCreate()等方法
8.到此,App便正式啓動,開始進入Activity生命週期,執行完onCreate/onStart/onResume方法,UI渲染後顯示APP主界面
————————————————
版權聲明:本文爲CSDN博主「學也不知義」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/hzwaill... android

Window是一個抽象類,表示一個窗口,具體實現類是PhoneWindow。
Window分爲3種,APP Window,系統Window和子Window,子Window必須依附在別的Window上。
setContentView中會生成一個PhoneWindow對象,這個PhoneWindow對象會生成DecorView,DecorView將會添加標題欄和遞歸解析content佈局,WindowManager會委託WindowManagerGlobal添加,會生成一個新的ViewRootImpl,並把DecorView和ViewRootImpl綁定起來,WindowManagerGlobal會經過幾個數組來儲存這些信息。
private final ArrayList<View> mViews = new ArrayList<View>();
private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
private final ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.LayoutParams>();
private final ArraySet<View> mDyingViews = new ArraySet<View>();
一個Window對應一個DecorView,對應一個ViewRootImpl。canvas

ViewRootImpl會負責與WMS進行通訊,並控制整個視圖的繪製。
其中繪製的起點是ViewRootImpl.performTraversals -> ViewRootImpl.performMeasure -> ViewRootImpl.performLayout - > ViewRootImpl.performDraw調用做爲根視圖DecorView的measure,layout,draw方法來遍歷視圖樹。
2018110215500034.png
20150706160043405 (1).png
做者:豆沙包67
連接:https://www.jianshu.com/p/a75...
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。windows

DecorView是一個Framelayout,從這裏進入View的measure,layout,draw過程。數組

Measure、Layout、Draw

測量種類分爲3種,測量相關都要經過MeasureSpec
1.MeasureSpec.EXACTLY:肯定模式,父容器但願子視圖View的大小是固定,也就是specSize大小。
2.MeasureSpec.AT_MOST:最大模式,父容器但願子視圖View的大小不超過父容器但願的大小,也就是不超過specSize大小。
3.MeasureSpec.UNSPECIFIED: 不肯定模式,子視圖View請求多大就是多大,父容器不限制其大小範圍,也就是size大小。
從content開始整個測量的流程,content比較特殊,它測量的初始參數由windows決定。
1.當DecorView根佈局的子視圖View寬高爲一個肯定值childDimension時,該View的測量模式爲MeasureSpec.EXACTLY,測量大小就是childDimension。
2.當子視圖View寬高爲MATCH_PARENT時,該View的測量模式爲MeasureSpec.EXACTLY,測量大小是父容器DecorView規定的大小,爲整個屏幕大小MATCH_PARENT。
3.當子視圖View寬高爲WRAP_CONTENT時,該View的測量模式爲MeasureSpec.AT_MOST,測量大小是父容器DecorView規定的大小,爲整個屏幕大小MATCH_PARENT。oop

1.View的measure方法是final類型的,子類不能夠重寫,子類能夠經過重寫onMeasure方法來測量本身的大小,固然也能夠不重寫onMeasure方法使用系統默認測量大小。
2.View測量結束的標誌是調用了View類中的setMeasuredDimension成員方法,言外之意是,若是你須要在自定義的View中重寫onMeasure方法,在你測量結束以前你必須調用setMeasuredDimension方法測量纔有效。
3.在Activity生命週期onCreate和onResume方法中調用View.getWidth()和View.getMeasuredHeight()返回值爲0的,是由於當前View的測量尚未開始,這裏關係到Activity啓動過程,文章開頭說了當ActivityThread類中的performResumeActivity方法執行以後纔將DecorView添加到PhoneWindow窗口上,開始測量。在Activity生命週期onCreate在中performResumeActivity還爲執行,所以調用View.getMeasuredHeight()返回值爲0。
4.子視圖View的大小是由父容器View和子視圖View佈局共同決定的。
20150707143727315 (1).png佈局

1.視圖View的佈局邏輯是由父View,也就是ViewGroup容器佈局來實現的。所以,咱們若是自定義View通常都無需重寫onMeasure方法,可是若是自定義一個ViewGroup容器的話,就必須實現onLayout方法,由於該方法在ViewGroup是抽象的,全部ViewGroup的全部子類必須實現onLayout方法。
2.當咱們的視圖View在佈局中使用 android:visibility=」gone」 屬性時,是不佔據屏幕空間的,由於在佈局時ViewGroup會遍歷每一個子視圖View,判斷當前子視圖View是否設置了 Visibility==GONE,若是設置了,當前子視圖View就會添加到父容器上,所以也就不佔據屏幕空間。具體能夠參考2-4節。動畫

3.必須在View佈局完以後調用getHeight()和getWidth()方法獲取到的View的寬高才大於0。具體能夠參考2-3節。

1.View繪製的畫布參數canvas是由surface對象得到,言外之意,View視圖繪製最終會繪製到Surface對象去。關於Surface內容參考3-1節。
2.由3-2小節咱們瞭解到,父類View繪製主要是繪製背景,邊框漸變效果,進度條,View具體的內容繪製調用了onDraw方法,經過該方法把View內容的繪製邏輯留給子類去實現。所以,咱們在自定義View的時候都通常都須要重寫父類的onDraw方法來實現View內容繪製。
3.無論任何狀況,每個View視圖都會繪製 scrollBars滾動條,且繪製滾動條的邏輯是在父類View中實現,子類無需本身實現滾動條的繪製。其實TextView也是有滾動條的,能夠經過代碼讓其顯示滾動條和內容滾動效果。你只需在TextView佈局設置android:scrollbars=」vertical」屬性,且在代碼中進行以下設置
textView.setMovementMethod(ScrollingMovementMethod.getInstance());
這樣既可以讓你的TextView內容能夠滑動,且有滾動條。
4.ViewGroup繪製的過程會對每一個子視圖View設置佈局容器動畫效果,若是你在ViewGroup容器佈局裏面設置了以下屬性的話:
android:animateLayoutChanges="true"
————————————————
版權聲明:本文爲CSDN博主「廢墟的樹」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/feiducl...spa

FrameLayout、LinearLayout、RelativeLayout

最經常使用的三個佈局
FrameLayout
較爲簡單,各個控件之間不互相干擾。.net

LinearLayout
會先測量一次沒有weight的控件大小,再把剩餘的空間再測量一輪由weight分線程

RelativeLayout
測量的時候肯定好座標

沉浸式

在Windows上除了content,可能還會出現titlebar,狀態欄、ActionBar、導航欄1.FullScrren會隱藏狀態欄2.NoTitleBar 會隱藏titleBar3.NoACtionBar 會隱藏ActionBar// todo