1. 程式人生 > >android中api簡介

android中api簡介

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獲取各種系統服務:

public abstract 
Object 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方法

performResumeActivity則是讓Activity呼叫onResume方法

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繫結一起。

詳細流程圖