android中api簡介
阿新 • • 發佈:2019-02-10
ViewTreeObserver 註冊一個觀察者來監聽檢視樹,當檢視樹的佈局、檢視樹的焦點、檢視樹將要繪製、
檢視樹滾動等發生改變時,ViewTreeObserver都會收到通知,ViewTreeObserver不能被例項化,可以呼叫
View.getViewTreeObserver()來獲得。
通過ViewTreeObserver .addOnPreDrawListener來獲得寬高,在執行onDraw之前已經執行了
onLayout()和onMeasure(),可以得到寬高了,當獲得正確的寬高後,請移除這個觀察者,
否則回撥會多次執行
//獲得ViewTreeObserver
ViewTreeObserver observer=view.getViewTreeObserver();
//註冊觀察者,監聽變化
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw()
{
if(observer.isAlive()){ observer.removeOnDrawListener(this);
}
//獲得寬高
int viewWidth=view.getMeasuredWidth();
int viewHeight=view.getMeasuredHeight();
return true; } });
6:Context獲取各種系統服務:
7:Window PhoneWindow https://www.jianshu.com/p/9da7bfe18374 詳細流程
每一個Activity都包含一個Window物件,Window物件通常由PhoneWindow實現PhoneWindow:將Decoriew設定為整個應用視窗的根View。是Window的實現類。它是Android中的最基本的視窗系統,每個Activity 均會建立一個PhoneWindow物件,是Activity和整個View系統互動的介面。DecorView:頂層檢視,將要顯示的具體內容呈現在PhoneWindow上.
DecorView是當前Activity所有View的祖先,它並不會向用戶呈現任何東西,它主要有如下幾個功能,可能不全:
setContentView原始碼簡單介紹:
而且Window也與WindowManager繫結。而mWindow,和mWindowManager則是Activity的成員變數。
可以看到這裡WindiwManager的建立是context.getSystemService(Context.WINDOW_SERVICE)
mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindow.setWindowManager( (WindowManager)context.getSystemService
r.window = r.activity.getWindow(); //賦值 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; //把當前的DecorView與WindowManager繫結一起 wm.addView(decor, l); }
r.window = r.activity.getWindow();
//賦值
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
//把當前的DecorView與WindowManager繫結一起 wm.addView(decor, l);
}
當前Activity的Window進而獲取到DecorView,再獲取當前Activity的WindowManager,將DecorView與WindowManager繫結一起。
詳細流程圖
檢視樹滾動等發生改變時,ViewTreeObserver都會收到通知,ViewTreeObserver不能被例項化,可以呼叫
View.getViewTreeObserver()來獲得。
通過ViewTreeObserver .addOnPreDrawListener來獲得寬高,在執行onDraw之前已經執行了
onLayout()和onMeasure(),可以得到寬高了,當獲得正確的寬高後,請移除這個觀察者,
否則回撥會多次執行
//獲得ViewTreeObserver
ViewTreeObserver observer=view.getViewTreeObserver();
//註冊觀察者,監聽變化
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override public boolean onPreDraw()
{
if(observer.isAlive()){ observer.removeOnDrawListener(this);
}
//獲得寬高
int viewWidth=view.getMeasuredWidth();
int viewHeight=view.getMeasuredHeight();
return true; } });
6:Context獲取各種系統服務:
public abstractObject getSystemService(@ServiceName @NonNull String name);
WINDOW_SERVICE = "window";
windowManager= (WindowManager) getSystemService(Context.WINDOW_SERVICE);
7:Window PhoneWindow https://www.jianshu.com/p/9da7bfe18374 詳細流程
每一個Activity都包含一個Window物件,Window物件通常由PhoneWindow實現PhoneWindow:將Decoriew設定為整個應用視窗的根View。是Window的實現類。它是Android中的最基本的視窗系統,每個Activity 均會建立一個PhoneWindow物件,是Activity和整個View系統互動的介面。DecorView:頂層檢視,將要顯示的具體內容呈現在PhoneWindow上.
DecorView是當前Activity所有View的祖先,它並不會向用戶呈現任何東西,它主要有如下幾個功能,可能不全:
- A. Dispatch ViewRoot分發來的key、touch、trackball等外部事件;
- B. DecorView有一個直接的子View,我們稱之為System Layout,這個View是從系統的Layout.xml中解析出的,
- 它包含當前UI的風格,如是否帶title、是否帶process bar等。可以稱這些屬性為Window decorations。
- C. 作為PhoneWindow與ViewRoot之間的橋樑,ViewRoot通過DecorView設定視窗屬性。
- //可以這樣獲取 View view = getWindow().getDecorView();
- DecorView只有一個子元素為LinearLayout。代表整個Window介面,包含通知欄,標題欄,內容顯示欄三塊區域。
- DecorView裡面TitleView:標題,可以設定requestWindowFeature(Window.FEATURE_NO_TITLE)
- 取消掉ContentView:是一個id為content的FrameLayout。
- 我們平常在Activity使用的setContentView就是設定在這裡,也就是在FrameLayout上
ViewGroup viewone= (ViewGroup) getWindow().getDecorView(); Log.d(TAG, "onCreate: getChildCount=="+viewone.getChildCount()); ViewGroup viewThree= (ViewGroup) viewone.getChildAt(0); if(viewThree instanceof LinearLayout){ Log.d(TAG, "onCreate: LinearLayout"); } Log.d(TAG, "onCreate: getChildCount=="+viewThree.getChildCount()); ViewGroup viewfour= (ViewGroup) viewThree.getChildAt(1); if(viewfour instanceof FrameLayout){ Log.d(TAG, "onCreate: FrameLayout"); } // 就是我們setContentView使用的view View viewTwo= findViewById(android.R.id.content); if(viewTwo instanceof FrameLayout){ Log.d(TAG, "onCreate: FrameLayout"); } if(viewTwo.equals(viewfour)){ Log.d(TAG, "onCreate: 同一個物件"); } // D/MainActivity: onCreate: getChildCount==1 // /MainActivity: onCreate: LinearLayout // D/MainActivity: onCreate: getChildCount==2 // D/MainActivity: onCreate: FrameLayout // D/MainActivity: onCreate: FrameLayout // D/MainActivity: onCreate: 同一個物件關鍵看Window的實現類PhoneWindow
setContentView原始碼簡單介紹:
getWindow().setContentView(layoutResID);
installDecor();
建立decorview 獲取我們設定的feature 就是為什麼我們需要在setContentView之前
呼叫設定feature的api
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
Window是一個抽象類,提供了各種視窗操作的方法,比如設定背景標題ContentView等等PhoneWindow則是Window的唯一實現類,它裡面實現了各種新增背景主題ContentView的方法,內部通過DecorView來新增頂級檢視每一個Activity上面都有一個Window,可以通過getWindow獲取DecorView,頂級檢視,繼承與FramentLayout,setContentView則是新增在它裡面的@id/content裡setContentView裡面建立了DecorView,根據Theme,Feature添加了對應的佈局檔案當setContentView設定顯示後會回撥Activity的onContentChanged方法啟動一個Activity流程:
ViewManager介面:
add and remove child views to an Activity 也是一個系統manager 通過getSystemService()獲取
addView UpdateViewLayout RemoveView
WindowManager:窗體管理器 實現了ViewManager介面
WindowManagerImpl:WindowManager實現類
Window窗體
ViewGroup也實現了ViewManager
可以看到在Activity建立到attach的時候,對應的Window視窗也被建立起來,而且Window也與WindowManager繫結。而mWindow,和mWindowManager則是Activity的成員變數。
可以看到這裡WindiwManager的建立是context.getSystemService(Context.WINDOW_SERVICE)
在建立號Activity之後 會建立Window和WindowManager
mWindow = new PhoneWindow(this);
mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
mWindow.setWindowManager( (WindowManager)context.getSystemService
(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
來建立Activity以及Activity所需要的Context,Window,呼叫了Activity的onCreate,onStart方法,
而接下來呼叫了handleResumeActivity方法
r.window = r.activity.getWindow(); //賦值 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; //把當前的DecorView與WindowManager繫結一起 wm.addView(decor, l); }
r.window = r.activity.getWindow();
//賦值
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
//把當前的DecorView與WindowManager繫結一起 wm.addView(decor, l);
}
當前Activity的Window進而獲取到DecorView,再獲取當前Activity的WindowManager,將DecorView與WindowManager繫結一起。
詳細流程圖